1

使用 CSS 选择器,选择器字符串body > h1.span订阅树中特定类型的节点。有谁知道这是怎么做到的?

转换的选择器,浏览器如何选择结果集?有没有让它高效的诀窍?

我想对于节点订阅的整个结构以及执行选择器查询时使用的整个结构存在某种层次类型树——但这只是一个猜测。

有谁知道真正的答案?或者更有趣的是,基于 jQuery/CSS 搜索查询在树上进行动态查找的最佳方法是什么?

4

2 回答 2

5

大多数主流浏览器根据DOM处理页面并根据页面中的元素创建文档层次结构或文档树。在应用 CSS 时,他们通常会迭代文档树,在每个元素的基础上工作,并对每个元素的样式表中的候选选择器执行从右到左的匹配,然后根据CSSOM应用基于这些匹配的 CSS 规则。这意味着对于像这样的选择器body > h1.span,浏览器首先检查每个元素以查看它是否h1具有 的类span,然后检查它是否是 的直接后代body

根据实现的不同,可能会有一些优化来过滤更有可能不匹配的情况。例如,在尝试任何其他匹配例程之前检查名称空间、标记名称、ID 或类名称,因为这些是区分元素的最常用方法。

这种逐元素匹配模式允许浏览器有效地“订阅”选择器对 DOM 中的更改,因为浏览器需要做的(我想)就是查看 DOM 中的更改并应用规则并重排元素进行了相应的更改。

不过,这过于简化了。它也主要指样式表中的选择器匹配。它没有描述每个选择器的实现,因为规范没有定义实现。

例如,浏览器以不同的方式实现Selectors APIdocument.querySelector()等),即使它使用CSS 选择器来查询 DOM。特别是,没有任何订阅模式;Selectors API 方法返回的节点列表不会动态更新。从§6.2 查找元素

该方法NodeList返回的对象querySelectorAll()必须是静态的,而不是实时的([DOM-LEVEL-3-CORE],第 1.1.1 节)。对基础文档结构的后续更改不得反映在NodeList对象中。这意味着该对象将包含一个匹配Element节点的列表,这些节点在创建列表时位于文档中。

根据this site上的一些答案,jQuery似乎也执行选择器的从右到左匹配,但我还没有找到任何支持来源。它还进行了许多优化,例如body首先读取 ID 选择器等。和 Selectors API 一样,jQuery 返回在调用其选择器引擎时匹配的静态节点列表;它不会订阅 DOM 中的更改并相应地更新节点列表(如果您需要订阅 DOM 更改并委托事件处理程序,则需要使用.on()或带有选择器的类似方法)。

值得注意的是,jQuery 采用的一项主要优化是遵循 Selectors API 以首先匹配选择器。这意味着它使用浏览器的本机实现而不是 JavaScript。如果选择器是有效的 CSS 且受支持,则document.querySelectorAll()返回节点列表。如果出错,jQuery 会使用自己的选择器引擎Sizzle来查询 DOM。

同样,它与浏览器对 CSS 选择器的实现并不完全相同,特别是因为 jQuery 选择器和 CSS 选择器不是一回事,尽管其中一个是对另一个的改编。

于 2012-09-25T08:34:27.013 回答
1

您可能知道 CSS 规则是从右到左评估的,因此在您的示例中,.span首先扫描整个 DOM 以查找类,然后按标签过滤h1

于 2012-09-25T08:35:25.087 回答