javascript – querySelector如何在引擎盖下工作?

每个人都知道像document.getElementByID(…)和document.querySelector(…)那样的DOM选择器以及如何将它与类,属性,id等一起使用.

但我无法找到它是如何工作的(我可以找到perf test comparisons,但我对理论感兴趣).我知道html页面是加载的,由浏览器解析并构建DOM树.但是每个选择器如何遍历DOM树以找到元素.

我看了一下spec for parsing algorithm并阅读了非常好的explanation how Browsers work,但它也提供了关于HTML,CSS解析和渲染流程的优秀解释,它没有解释每个选择器如何遍历这个树来查找元素.

我假设为了找到类似.black或span的东西,它需要遍历整个树,但是为了找到#id,它可能会遍历一些额外的数据结构,从而使它更快.请不要写下你的假设,我正在寻找具备备份到规范或在某些浏览器中实现的具体知识.

解决方法

检查 Firefox’s source并阅读 the related documentation将有助于获得一些初步见解.
获取文档后,将其传递给解析器(参见: /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(…))通过粘合代码和过多的对象层次结构连接到此哈希映射,请参阅“How is the web-exposed DOM implemented?” on ask.mozilla.org.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...