猜猜以下HTML DOM的正文片段:
...
<div class="entry">
<div class="evil">
<div class="some-other-class">
<pre>My foo text</pre>
</div>
</div>
</div>
<div class="entry">
<div class="nice">
<pre>My nice text</pre>
</div>
</div>
...
使用jQuery我想选择属于<pre>
类型的父元素的所有div.entry
元素,不是div.evil
的后代。更确切地说:我想将特定的类应用于那些“非邪恶的”<pre>
元素。
我使用了:not
选择器过滤器以及.not()
方法来构建链,以便在应用类之前选择适当的子集和后代元素,如下所示:
$("div.entry div:not(.evil) pre").addClass("pretty");
另外:
$("div.entry").not("div.evil").find("pre").addClass("pretty")
这两个变体导致匹配所有pre
元素,包括那些带有“邪恶”父div的那些!
然而,当我选择一个直接的父级加上类和这样的孩子时:
$("div.entry div:not(.some-other-class) > pre").addClass("pretty");
它按预期工作。首先,我认为我误解了使用element1 element2
的后代元素选择。使用链式过滤器方法没有成功,但证明了其他东西必定是错误的。
问题本身听起来并不难,但它现在让我疯狂。
任何想法是否以及为何我的选择方式可能都是错的?
答案 0 :(得分:3)
我建议:
$('div.entry pre').filter(function(){
return !$(this).closest('div.evil').length
});
对我来说,优点是你只需选择所有 pre
元素,然后根据(相当)简单的父评估减少这些元素。替代方法同样有效,这只是......我个人的偏好。
答案 1 :(得分:3)
保持简单:
$('div.entry pre:not(div.evil pre)');
在这里:jsfiddle demo
注意强>
那么,为什么
$("div.entry div:not(.evil) pre");
不起作用?
当您要求div:not(.evil)
时,jQuery人会返回div.some-other-class
以及div.nice
,以便最终选择器为:
$("div.entry div.some-other-class pre, div.entry div.nice pre");
甚至与pre
的后代相匹配,后者是坏的,坏的,div.evil
!
答案 2 :(得分:2)
您可以使用:has
选择器:
$("div.entry:not(:has(.evil)) pre").addClass("pretty");
或者:
$('div.entry').not(':has(.evil)').find('pre').addClass("pretty");