我正在试图找出以下标记的选择器。我想要除了包含blockquote 的节点之外的所有节点。 <blockquote>
将永远是<div>
的直接孩子,它将成为<body>
代码的直接子女。
示例HTML:
<ul>
<!-- Lots of HTML -->
</ul>
<div>
<p>
<!-- Lots of other HTML -->
</p>
</div>
<div>
<blockquote>Some text I don't care about</blockquote>
</div>
预期结果:
<ul><!-- Lots of HTML --></ul>
<div><p><!-- Lots of other HTML --></p></div>
尝试选择器:
document.querySelectorAll("body > :not(div > blockquote)")
我尝试了以上操作,但是我无法在:not()
选择器中放置一个直接的子选择器。尝试失败的Here is a fiddle。
我目前不在,也不能使用jQuery。
答案 0 :(得分:4)
你不能原生地这样做。在任何当前的选择器规范中,无法通过子节点过滤元素。 (但是,这可能会出现在未来的选择器规范中。)
因此,您需要自己进行过滤。这并不是特别困难。一种方法是选择所有相关元素,然后过滤掉你不想要的元素:
Array.prototype.slice.call(document.querySelectorAll("body > *"))
.filter(function(el) {
return !el.querySelector(':scope > blockquote');
})
这会将选择变为数组,然后使用Array#filter
方法去掉所有包含blockquote
元素的方法。
显然,这比原生选择器的性能差得多,但它是在当前JS中做你想要的唯一方法。
正如BoltClock正确指出的那样,:scope
还不是官方标准。由于Chrome 支持它,我被一种虚假的安全感所迷惑:其他浏览器还没有。如果要在任何级别排除包含blockquote
元素的任何顶级元素,最好的方法是:
return !el.querySelector('blockquote');