选择器 scope

选择器:scope

在 CSS 选择器中,:scope​ 是一个伪类(pseudo-class),用于表示当前元素的作用域。它的作用是限制选择器的范围,使其相对于某个特定的上下文(通常是某个 DOM 元素)进行匹配。


什么是 :scope

  • :scope​ 表示当前上下文中的“根元素”。
  • querySelector​ 或 querySelectorAll​ 中使用时,:scope​ 通常指代调用方法的那个 DOM 元素本身(即 this​ 的上下文)。
  • 它的主要用途是确保选择器的作用范围被限定在当前元素内部,而不是全局搜索。

在你的代码中的含义

querySelectorAll(":scope > .b3-list-item > .b3-list-item__toggle > .b3-list-item__arrow--open")
  1. :scope的作用

    • 假设这段代码是在某个 DOM 元素上调用的(例如 element.querySelectorAll(...)​),那么 :scope​ 指代的就是这个 element​。
    • 也就是说,选择器会从 element​ 开始查找,而不会向上或向外扩展到整个文档。
  2. 完整解释

    • :scope > .b3-list-item​:从当前元素(:scope​)的直接子元素中查找具有类名 .b3-list-item​ 的元素。
    • .b3-list-item > .b3-list-item__toggle​:进一步查找 .b3-list-item​ 的直接子元素中具有类名 .b3-list-item__toggle​ 的元素。
    • .b3-list-item__toggle > .b3-list-item__arrow--open​:继续查找 .b3-list-item__toggle​ 的直接子元素中具有类名 .b3-list-item__arrow--open​ 的元素。

为什么需要 :scope

  1. 避免全局污染
    如果不使用 :scope​,选择器可能会在整个文档范围内查找匹配的元素,这可能导致意外的结果。使用 :scope​ 可以将搜索范围限定在当前元素及其后代中。
  2. 提高性能
    通过限定作用范围,可以减少 DOM 遍历的范围,从而提高查询效率。
  3. 更清晰的语义
    使用 :scope​ 可以明确表示你希望从当前元素开始查找,而不是从整个文档或其他上下文中查找。

示例代码

以下是一个完整的示例,展示 :scope​ 的作用:

HTML

<div id="container">
    <div class="b3-list-item">
        <div class="b3-list-item__toggle">
            <span class="b3-list-item__arrow--open">Open</span>
        </div>
    </div>
</div>

<div class="b3-list-item">
    <div class="b3-list-item__toggle">
        <span class="b3-list-item__arrow--open">Open (Outside)</span>
    </div>
</div>

JavaScript

const container = document.getElementById('container');

// 使用 :scope 限定范围
const matches = container.querySelectorAll(
    ":scope > .b3-list-item > .b3-list-item__toggle > .b3-list-item__arrow--open"
);

console.log(matches); // 输出 NodeList,包含 "Open" 的 span 元素

解释

  • :scope​ 限定了选择器的作用范围为 #container​。
  • 因此,只有 #container​ 内部的 .b3-list-item​ 和其子元素会被匹配。
  • 外部的 <div class="b3-list-item">​ 不会被选中。

浏览器兼容性

:scope​ 是现代浏览器支持的一个标准特性,但在一些较旧的浏览器中可能存在兼容性问题。以下是主要浏览器的支持情况:

浏览器 支持版本
Chrome 63+
Firefox 32+
Edge 79+
Safari 10.1+
Internet Explorer 不支持

如果你需要兼容老旧浏览器,可以通过其他方式(如手动遍历子元素)来实现类似的功能。


替代方案(如果不支持 :scope

如果目标浏览器不支持 :scope​,可以通过以下方法实现类似功能:

  1. 手动限定范围
    使用 element.children​ 或 element.querySelectorAll​ 手动限定范围。例如:

    const container = document.getElementById('container');
    const matches = Array.from(container.children)
        .filter(child => child.matches('.b3-list-item'))
        .map(item => item.querySelector('.b3-list-item__toggle > .b3-list-item__arrow--open'))
        .filter(Boolean); // 过滤掉 null
    
    console.log(matches);
    
  2. 使用 Shadow DOM
    如果你在 Web Components 中工作,可以利用 Shadow DOM 的封装特性,避免全局污染。


总结

  • :scope​ 是一个伪类,用于表示当前元素的作用域。
  • querySelector​ 或 querySelectorAll​ 中使用时,:scope​ 限定了选择器的作用范围,使其仅在当前元素及其后代中查找。
  • 它的主要优点是避免全局污染、提高性能和增强代码可读性。

如果你有更多关于 :scope​ 或其他选择器的问题,请随时补充说明!

image.png

留下你的脚步
推荐阅读