将jQuery选择器翻译为javascript的querySelector语句

4

我正在尝试使用querySelector来复制这个jQuery选择器:

$("*:not(#player > div)")

我知道可以使用querySelector('*')选择所有元素,但如何排除与#player > div匹配的元素?


您可以在 querySelector 中使用所有浏览器支持的 CSS 选择器,因此如果您的浏览器支持 :not,那么就可以直接使用。 - m90
2
但是,:not(#id > child) 不被支持。 - adeneo
1
这可能意味着你需要迭代和过滤,但通常不应该使用星号选择器,因此可能有更好的解决方法。 - adeneo
2个回答

3
大多数 jQuery 选择器可以转换为 querySelector() 或 CSS,但并非全部,因为 jQuery 扩展了某些现有的选择器,并引入了完全非标准的选择器。
在你的特定情况下,与 jQuery 不同,CSS 中的 :not() 只接受一个简单的选择器。 #player > div 是一个复杂的选择器,由两个简单选择器和一个组合器组成。有关详细信息,请参见此问题: 为什么我的 jQuery :not() 选择器在 CSS 中不起作用? 没有标准化的等效项适用于您的 jQuery 选择器。 您将不得不单独排除 #player > div 元素,通过执行 document.querySelectorAll('#player > div') 并从原始元素集中删除匹配该集合的元素。
...实际上,虽然没有办法在单个复杂选择器中表示 :not(#player > div),但是由于 > 组合器,仍然可以使用不少于四个复杂选择器列举所有可能性:
:root, :not(#player) > div, #player > :not(div), :not(#player) > :not(div)

这是一个概念验证:

// The following JS + CSS should give all matching elements a 1px solid red border
$(':not(#player > div)').css('border-color', 'red');
* { margin: 10px; }
html::before { content: 'html - Match'; }
body::before { content: 'body - Match'; }

:root, :not(#player) > div, #player > :not(div), :not(#player) > :not(div) {
  border-style: solid;
  border-width: 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>body > p - Match</p>
<div>body > div - Match</div>
<div>
  body > div:not(#player) - Match
  <p>:not(#player) > p - Match</p>
  <div>:not(#player) > div - Match</div>
</div>
<div id=player>
  body > div#player - Match
  <p>#player > p - Match</p>
  <div>
    #player > div - Non-match
    <div>#player > div:not(#player) > div - Match</div>
  </div>
</div>

但是,如果你要从原始集合中选择这些元素并将其删除,就像上面所描述的那样,或者只需获取一个matches() polyfill并以此方式排除元素,那么你依然会获得更好的体验。


0
使用此功能可删除不需要的元素。
var el = Array.prototype.slice.call(document.querySelectorAll('*'),0)
el.splice(el.indexOf(document.querySelectorAll('html')),1)

我认为这永远不会起作用... Array#indexOf 只能处理一个要在数组中定位的元素。 - yckart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接