2012-12-14 22 views
16

Giả sử tôi có HTML sau:Chọn yếu tố trừ khi nó có một tổ tiên của một lớp được sử dụng chỉ là một selector

<div class="foo"> 
    <ul> 
    <li>One</li> 
    <li>Two</li> 
    </ul> 
</div> <!-- not originally here --> 
<div class="bar"> 
    <ul> 
    <li>Three</li> 
    <li>Four</li> 
    </ul> 
</div> 

Tôi muốn chọn tất cả li yếu tố đó là không hậu duệ của một phần tử với class foo. Tôi biết tôi có thể làm điều đó với một ưa thích filter function, nhưng tôi tự hỏi liệu tôi có thể làm điều đó chỉ với một bộ chọn. Đầu tiên tôi đã cố gắng:

$(":not(.foo) li") 

Thật không may điều này không làm việc kể từ khi li tổ tiên khác mà không có phong cách (các ul trong trường hợp này). Sau đây dường như làm việc;

$(":not(.foo) :not(.foo) li") 

Nói cách khác, chọn tất cả li yếu tố mà không có tổ tiên mà một trong hai có lớp foo hoặc có tổ tiên của riêng của mình với lớp foo. Có lẽ đây là cách tốt nhất/duy nhất để làm điều đó với một bộ chọn, nhưng tôi không hồi hộp về sự lặp lại của bộ chọn :not. Có ý tưởng nào tốt hơn không?

fiddle

+2

Vấn đề ở đây là ': không (.foo) li' không có nghĩa là "'li' mà không có tổ tiên có lớp 'foo'".Nó có nghĩa là "' li' có một tổ tiên không có lớp 'foo'". Sự khác biệt có vẻ tinh tế, nhưng nó thực sự là một sự khác biệt rất lớn. – BoltClock

+0

Đúng vậy. Và cái thứ hai có nghĩa là 'li' có một tổ tiên không có lớp' foo' AND không có tổ tiên của riêng nó với lớp 'foo'. Mà tôi nghĩ là kết quả đúng, nhưng là một cách khá xấu xí và không hài lòng để đạt được điều đó. –

Trả lời

24

Bạn có thể làm điều đó như thế này

$("li").not('.foo li') 

http://jsfiddle.net/y7s54/

hoặc

$("li:not(.foo li)") 

http://jsfiddle.net/QpCYY/

Chọn tất cả của li mà không có một tổ tiên với lớp foo

+0

Điều này có vẻ như là câu trả lời hay nhất cho tôi trừ khi ai đó có tranh cãi ngược lại. –

+0

Tôi đồng ý; nó tốt hơn so với câu trả lời của tôi. – DNS

0

Làm thế nào về điều này:

$("li:not(.foo > li)") 

Các ý kiến ​​trong các tài liệu là khá hữu ích nếu điều này không làm việc:

http://api.jquery.com/not-selector/

+0

no - http://jsfiddle.net/HsPSv/1/ –

+0

Đó là ý tưởng cơ bản đúng, nhưng không hoạt động, vì lis không phải là hậu duệ trực tiếp của .foo. – DNS

4

Hãy thử li:not(.foo > ul > li); mà chọn tất cả lis trừ những người có cha mẹ .foo hai cấp lên.

+0

Tôi không chắc tại sao OP lại * không hồi hộp về sự lặp lại của bộ chọn ': not' *. Những gì bạn đã viết có lẽ là tốt trong JQuery/Sizzle, nhưng theo thông số CSS3, bộ chọn ': not' chỉ có thể chứa [bộ chọn đơn giản] (http://www.w3.org/TR/css3-selectors/ # đơn giản-selectors-dfn). – kojiro

+0

@kojiro: Có lẽ vì lặp lại bộ chọn ': not' theo cách tương thích với CSS3 [không thực sự hoạt động] (http://stackoverflow.com/questions/7084112/css-negation-pseudo-class-not -cho-cha mẹ-tổ tiên-yếu tố/7084147 # 7084147). Cách duy nhất để làm điều này bằng cách sử dụng ': not' không phụ thuộc vào bản chất của đánh dấu là bằng cách sử dụng nó theo cách không chuẩn được cung cấp bởi jQuery/Sizzle, như được đưa ra trong câu trả lời này. – BoltClock

+0

@BoltClock Nó hoạt động tốt. Nó không chỉ là những gì bạn có thể mong đợi. – kojiro

2

Bạn có thể làm điều đó bằng bối cảnh cùng với selector như dưới,

$('li', $('div:not(.foo)')) 

LIve Demo

$('li', $('div:not(.foo)')).each(function(){ 
    alert($(this).text()); 
});​ 
+0

+1 - điều này tránh được sự kỳ quặc của việc sử dụng ': not' với công cụ chọn không đơn giản và có khả năng hiệu quả hơn so với thực hiện tra cứu bằng CSS thuần túy. – kojiro

+1

Trên thực tế, nó không hiệu quả hơn trừ khi bạn loại bỏ các dấu ngoặc kép bên trong từ ': not()' - có chúng không cần thiết, và là CSS không hợp lệ để nó không nhanh hơn. Xem http://stackoverflow.com/questions/12475595/why-do-the-not-and-has-selectors-allow-quoted-arguments – BoltClock

+0

Điều này cũng không thành công nếu bất kỳ tổ tiên nào của 'div.foo' là' div : không (.foo) '. – BoltClock

0

Tôi nghĩ rằng giải pháp này có vẻ một chút đẹp hơn, nhưng có một chút tranh cãi trên Nhận xét API về sự khác biệt về tốc độ.

$("li").not(".foo li") 

fiddle

Các vấn đề liên quan