querySelector是如何在后台工作的
How does querySelector works under the hood?
每个人都知道像document.getElementByID(...)
和document.querySelector(...)
这样的DOM选择器的作用,以及如何将其与类、属性、id等一起使用。
但我不知道它是如何在引擎盖下工作的(我可以找到性能测试的比较,但我对理论感兴趣)。我知道html页面是加载的,由浏览器解析,并构建DOM树。但是每个选择器是如何遍历DOM树来找到元素的呢。
我看了一份解析算法的规范,并阅读了浏览器如何工作的非常好的解释,但它也提供了关于HTML、CSS解析和渲染流的出色解释——它没有解释这些选择器中的每个选择器如何遍历这棵树来查找元素。
我假设,为了找到类似.black
或span
的东西,它需要遍历整个树,但要找到#id
,它可能需要遍历一些额外的数据结构,从而使其更快。请不要写你的假设,我正在寻找一些浏览器中备份到规范或实现的具体知识。
检查Firefox的源代码并阅读相关文档将有助于获得一些初步见解
获取文档后,它将被传递给解析器(请参见:/mozilla/parser/html/),解析器将仔细阅读文档并生成内容树。解析器的核心部分是用Java(/mozilla/parser/html/javasrc/)编写的,然后翻译成C++进行构建,因此,当您想阅读源代码的其余部分时,请做好准备。
查看解析器的源代码(/mozilla/parser/html/javasrc/TreeBuilder.java),即函数startTag
:的摘录
1579 if (errorHandler != null) {
1580 // ID uniqueness
1581 @IdType String id = attributes.getId();
1582 if (id != null) {
1583 LocatorImpl oldLoc = idLocations.get(id);
1584 if (oldLoc != null) {
1585 err("Duplicate ID 'u201C" + id + "'u201D.");
1586 errorHandler.warning(new SAXParseException(
1587 "The first occurrence of ID 'u201C" + id
1588 + "'u201D was here.", oldLoc));
1589 } else {
1590 idLocations.put(id, new LocatorImpl(tokenizer));
1591 }
1592 }
1593 }
将注意力转移到第1590行,并记住在同一文件的早些时候我们有:
459 private final Map<String, LocatorImpl> idLocations = new HashMap<String, LocatorImpl>();
我们可以看到,节点id保存在一个简单的哈希映射中。查找类是如何处理的是留给读者的练习。
不同的DOM方法,例如document.getElementByID(...)
,通过粘合代码和过多的对象层次结构连接到这个哈希图,请参阅ask.mozilla.org上的"web公开的DOM是如何实现的?"。
- Chrome扩展程序在后台工作
- ngRoute 在 angularjs 中作为依赖项包含在后台时如何工作
- 无法通过“&”使nodejs在后台工作
- jQuery Mobile App 的后台工作线程
- Chrome 扩展程序:无法让消息传递在后台脚本和内容脚本之间正常工作
- addEventListener 如何在后台工作
- heroku上的后台工作网络是如何知道的's结束了
- 没有web工作程序的Javascript后台处理
- querySelector是如何在后台工作的
- Javascript-事件监听器如何在后台工作
- jQuery点击事件不工作时,全屏iframe在后台
- 改变后台javascript功能不工作
- 在node.js中使用工作/后台进程vs .异步调用
- Ajax表单重载页面,而不是在后台工作
- 为什么css后台jQuery代码不工作jQuery设置多个css值
- 如何使一个phonegap构建应用程序在后台工作
- 使用canvas创建桌面通知图像,只有一个图像可以从后台页面工作
- force.start (d3.js) 是否在后台工作
- selenium (Firefox后台),sendkeys工作,但不聚焦
- 在HTML5应用程序中下载后台数据到浏览器数据库- settimeout vs工作线程