likes
comments
collection
share

浏览器是如何解析CSS选择器的?从右向左的匹配规则, 只有第一次会遍历所有元素找节点, 而剩下的就是在看父辈祖辈是否满足

作者站长头像
站长
· 阅读数 46

在生成渲染树的过程中,渲染引擎会根据选择器提供的信息来遍历 DOM 树,找到对应的 DOM 节点后将样式规则附加到上面。

来看一段样式选择器代码,以及一段要应用样式的 HTML:

CSS

.box div span {
  font-size: 20px;
}

HTML

<div class="box">
  <header>
    <h3>
      <span>这是一个标题</span>
    </h3>
  </header>

  <div>
    <ul>
      <li><a href="http://">内容一</a></li>
      <li><a href="http://">内容二</a></li>
      <li><a href="http://">内容三</a></li>
    </ul>
  </div>
</div>

渲染引擎是怎么根据上述样式选择器去遍历这个 DOM 树的呢?是按照从左往右的选择器顺序去匹配,还是从右往左呢?

为了更直观的查看,我们先将这棵 DOM 树先绘制成图:

浏览器是如何解析CSS选择器的?从右向左的匹配规则, 只有第一次会遍历所有元素找节点, 而剩下的就是在看父辈祖辈是否满足

然后我们来对比一下两种顺序的匹配:

从左往右:.box => h3 => span

  1. 遍历所有的元素, 找有 .box 类的节点

  2. .box 开始遍历所有的⼦孙节点 headerdivh3ul ....

    遍历所有的后代元素后, 知道了, 整个子孙后代只有一个 h3

  3. 找到 h3 , 还要继续重新遍历 h3 的所有子孙节点, 去找 span

    ...

问题: 会进行大量树形结构子孙节点的遍历, 这是非常消耗成本的 !

这在真实页面中⼀棵 DOM 树的节点成百上千的情况下,这种遍历方式的效率会非常的低,根本不适合采用。

从右往左:span => h3 => .mod-nav

  1. 先找到所有的 span 节点 ,然后基于每⼀个 span 再向上查找 h3

  2. h3 再向上查找 .mod-nav 的节点

  3. 最后触及根元素 html 结束该分⽀遍历

    ...

从右向左的匹配规则, 只有第一次会遍历所有元素找节点, 而剩下的就是在看父辈祖辈是否满足选择器的条件, 匹配效率大大提升!

因此,浏览器遵循 “从右往左” 的规则来解析 CSS 选择器!

转载自:https://juejin.cn/post/7420780282881081344
评论
请登录