2012-12-11 40 views
19

Cách thanh lịch nhất để kiểm tra xem một phần tử có nằm trong luồng thông thường bằng jQuery không?JQuery: kiểm tra xem phần tử có đang ở dòng bình thường hay không

Theo CSS3 specification,

Một hộp thuộc về dòng chảy nếu:

Giá trị sử dụng của 'display' của nó là 'khối', 'danh mục', 'bảng 'hoặc mẫu.

Giá trị được sử dụng của ‘phao’ được sử dụng là ‘không’.

Giá trị được sử dụng của ‘vị trí’ của nó là ‘tĩnh’ hoặc ‘tương đối’.

Đó là con của dòng chảy hoặc con của một hộp thuộc dòng chảy.

Tôi có nên kiểm tra tất cả các điều kiện này hoặc có cách nào tốt hơn không?

+3

câu hỏi đầu tiên của tôi là, tại sao bạn cần phải biết điều này? Bạn có thể chỉ cần kiểm tra một trong những phẩm chất này trong ứng dụng thực tế của bạn. – Blazemonger

+0

Nếu đây là định nghĩa chỉ được sử dụng trong đặc điểm kỹ thuật, bạn nên kiểm tra các điều kiện thực tế. – pimvdb

+0

Tôi đang làm việc trên một dự án phụ cá nhân có liên quan đến việc sao chép và dán nội dung theo kiểu trong trình duyệt. Tôi muốn loại bỏ lề trên của phần tử đầu tiên trong luồng và lề dưới của phần tử cuối cùng trong luồng. – sbichenko

Trả lời

3

Tôi nghĩ một yêu cầu "trong dòng" khác là overflow được đặt thành visible.

From the CSS2 spec:

Floats, yếu tố hoàn toàn vị trí, container khối (như inline-block, bảng tế bào, và bảng chú thích) mà không chặn hộp, và hộp khối với 'tràn' khác hơn 'có thể nhìn thấy' (trừ khi giá trị đó được truyền đến khung nhìn) thiết lập các bối cảnh định dạng khối mới cho nội dung của chúng.

Dựa trên các yêu cầu bạn trích dẫn và yêu cầu overflow, đây là một cách để làm điều đó với jquery:

function isInFlow(elm, ctxRoot) { 

    ctxRoot = ctxRoot || document.body; 

    var $elm = $(elm), 
     ch = -1, 
     h; 

    if (!$elm.length) { 
     return false; 
    } 

    while ($elm[0] !== document.body) { 
     h = $elm.height(); 
     if (h < ch || !okProps($elm)) { 
      return false; 
     } 
     ch = h; 
     $elm = $elm.parent(); 

     if (!$elm.length) { 
      // not attached to the DOM 
      return false; 
     } 
     if ($elm[0] === ctxRoot) { 
      // encountered the ctxRoot and has been 
      // inflow the whole time 
      return true; 
     } 
    } 
    // should only get here if elm 
    // is not a child of ctxRoot 
    return false; 
} 

function okProps($elm) { 

    if ($elm.css('float') !== 'none'){ 
     return false;  
    } 
    if ($elm.css('overflow') !== 'visible'){ 
     return false;  
    } 
    switch ($elm.css('position')) { 
     case 'static': 
     case 'relative': 
      break; 
     default: 
      return false; 
    } 
    switch ($elm.css('display')) { 
     case 'block': 
     case 'list-item': 
     case 'table': 
      return true; 
    } 
    return false; 
} 
​ 

Xem này jsFiddle cho các trường hợp kiểm tra.

Tôi không chắc chắn sẽ tốt hơn nếu sử dụng window.getComputedStyle() hay không.

Chức năng đang kiểm tra xem elm có ở trong ngữ cảnh định dạng luồng hoặc chặn của ctxRoot (như trước đây được gọi là, tôi nghĩ). Nếu ctxRoot không được cung cấp, nó sẽ kiểm tra phần tử body. Điều này không kiểm tra để đảm bảo rằng ctxRoot đang hoạt động. Như vậy, với HTML này

<div id="b" style="overflow: hidden;"> 
    <div id="ba">ba 
     <p id="baa">baa</p> 
     <span id="bab">bab</span> 
     <span id="bac" style="display:block;">bac</span> 
    </div> 
</div> 

Các trường hợp kiểm tra là:

var b = $('#b')[0]; 
console.log('no ',isInFlow(b)); 
console.log('no ',isInFlow('#ba')); 
console.log('yes ',isInFlow('#ba', b)); 
console.log('no ',isInFlow('#baa')); 
console.log('yes ',isInFlow('#baa', b)); 
console.log('no ',isInFlow('#bab')); 
console.log('no ',isInFlow('#bab', b)); 
console.log('no ',isInFlow('#bac')); 
console.log('yes ',isInFlow('#bac', b)); 
+0

Được chấp nhận cho các trường hợp phân tích và kiểm tra chuyên sâu. Các giải pháp khác đã được chứng minh là sai trong một số trường hợp. – sbichenko

4

tôi nghi ngờ theres một cách tốt hơn, nhưng theo một cách khác sẽ là:

1) Đắm phần tử với một wrapper

2) Hãy so sánh chiều cao và chiều rộng của wrapper với bọc yếu tố

Ví dụ:

$('#elementToTest').clone().addClass('clone').wrap('<div></div>') 
if($('#elementToTest.clone').height()>$('#elementToTest.clone').parent().height()){ 
    //outside the normal flow 
} 
+0

Bạn có thể giải thích về cách chính xác điều này sẽ làm việc? – sbichenko

+0

đã thêm một ví dụ –

+0

Xin lỗi, ý tôi là: làm thế nào điều này sẽ kiểm tra xem một phần tử có đang ở trong luồng thông thường không? – sbichenko

0

Thay vì nhìn nó hồi tố, bạn có thể trước empt nhu cầu này bằng cách sử dụng các chú thích dữ liệu. Bất kỳ khi nào bạn tạo hoặc xác định phần tử, hãy đặt thuộc tính của nó data-flow thành true hoặc false.

Ví dụ:

var newDiv = document.createElement("div"); 
newDiv.style.position = "absolute"; 
newDiv.setAttribute("data-flow","false"); 

Hoặc trong html

<div style="position:absolute;" data-flow="false"></div> 

Và sau đó bạn chỉ có thể chọn những yếu tố này với một selector:

$('*[data-flow=false]') 
Các vấn đề liên quan