在querySelector和 querySelectorAll的选择器字符串中对 :scope的使用

前端开发 2026-07-09

在查看MDN上关于 :scope 的文档时,我有点困惑,因为我最初是从限制结果仅限于该元素的子节点来理解的,但实际情况是它将选择器字符串的作用域限定为该元素的子节点,且不包含该元素本身。

应该将 elem.querySelectorAll(':scope ...') 设为默认,除非结果需要包含基于DOM中的 elem 的祖先节点或更高层级所选中的子节点?

或者只有在不使用 :scope 时结果不是所期望的情况下才应该使用它?

换句话说,如果有无 :scope 的结果始终相同,使用 :scope 是减少工作量还是增加搜索过程的工作量?

此外,是否正确地说 elem.querySelectorelem.querySelectorAll 总是对整个文档进行搜索,然后再将结果限制为 elem 的子节点,而不是从 elem 开始搜索?

解决方案

:scope 将会把选择器的起始点设定到调用 querySelector 的元素上。没有它,选择器将从根节点开始,在DOM中向上查找更高层级的元素。如果你习惯CSS的嵌套语法,那么它大致上就相当于 & selector(顺便说一句,它也可以使用):

const source = document.getElementById("source");
const test = (selector) =>
  console.log(`${selector}:`, source.querySelector(selector));

test("body span"); // <span></span>
test(":scope body span"); // null
test("body :scope span"); // <span></span>
test("& body span"); // null
test("body & span"); // <span></span>
test(":scope span:is(body *)"); // <span></span>
<div id="source">

  <span></span>

</div>

然而,使用 :scope 并不表示引擎就不需要从文档根部查找。正如上面的例子所示,它可以放在选择器的任意位置,甚至在选择器中你也可以包含 :is() 伪类,使查找回溯整棵树。

至于该选择器是在结果相同的情况下增加还是减少工作量,这很可能取决于引擎,但我预计在大多数情况下不会有明显差异。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章