Javascript document.getElementById()如何搜索DOM树?

Javascript document.getElementById()如何搜索DOM树?,javascript,html,performance,dom,search,Javascript,Html,Performance,Dom,Search,我知道一些浏览器(现在大多数?)使用ID创建所有元素的哈希表。因此,在本例中,调用document.getElementById()就可以搜索哈希表。但是,在DOM树的上下文中,它将如何做到这一点呢?例如,它是深度优先搜索吗 我这样问是因为我想知道放置DOM元素最快的位置在哪里,所以在搜索本身开始时,它就会在搜索中找到 快速查看,无法找到有关此主题的任何具体信息 非常感谢您的帮助。因为DOM实现依赖于浏览器,所以每个浏览器可能以不同的方式实现它。还有一种情况是,浏览器确实有一个所有ID的哈希映射

我知道一些浏览器(现在大多数?)使用ID创建所有元素的哈希表。因此,在本例中,调用document.getElementById()就可以搜索哈希表。但是,在DOM树的上下文中,它将如何做到这一点呢?例如,它是深度优先搜索吗

我这样问是因为我想知道放置DOM元素最快的位置在哪里,所以在搜索本身开始时,它就会在搜索中找到

快速查看,无法找到有关此主题的任何具体信息


非常感谢您的帮助。

因为DOM实现依赖于浏览器,所以每个浏览器可能以不同的方式实现它。还有一种情况是,浏览器确实有一个所有ID的哈希映射,并使用它执行
document.getElementById

为了了解浏览器在DOM中查找的顺序,您可以查看
文档.all
集合,该集合包含
文档中所有DOM元素的普通列表。就Chrome、Safari和Firefox而言,似乎是DFS

另一个有趣的问题是:如果同一文档中的两个元素具有相同的ID,那么
document.getElementById
将返回哪个元素。使用下面的代码段可以看到,它是使用DFS算法找到的第一个元素(至少在下面提到的浏览器中)

HTML

<div>
  <div id="id" data-index="DFS"></div>
</div>
<div id="id" data-index="BFS"></div>
控制台输出

console.log(document.getElementById('id').getAttribute('data-index'));
DFS
function Div(el) {
    var div = document.createElement('div');
    el.appendChild(div);
    return div;
}

var i, body, el, t0, t1;

el = body = document.querySelector('body');
for(i=0; i<10000; i++) {
    el = new Div(el);
    el.setAttribute('id', 'ix'); // <- setting id="id" in this line will produce ~10x time difference
}
el.setAttribute('id', 'id');

el = new Div(body);
el.setAttribute('id', 'id');

t0 = performance.now();
document.getElementById('id');
t1 = performance.now();

console.log('Time to find element by ID: ' + (t1 - t0) + 'ms');
Plunker

编辑:

关于回答评论中的其他问题

我不确定搜索是否会在第一个结果的位置停止,这当然会更快…有没有办法测试这一点

在下面,您可以找到一个代码片段,它创建了10000个元素,一个在另一个元素内部,一个同级元素。在一种情况下,相同的ID设置为最深的元素和同级元素,在另一种情况下设置为所有元素。第二种情况比第一种情况快约10倍。这证明在找到具有匹配ID的第一个元素后,搜索将停止

JavaScript

console.log(document.getElementById('id').getAttribute('data-index'));
DFS
function Div(el) {
    var div = document.createElement('div');
    el.appendChild(div);
    return div;
}

var i, body, el, t0, t1;

el = body = document.querySelector('body');
for(i=0; i<10000; i++) {
    el = new Div(el);
    el.setAttribute('id', 'ix'); // <- setting id="id" in this line will produce ~10x time difference
}
el.setAttribute('id', 'id');

el = new Div(body);
el.setAttribute('id', 'id');

t0 = performance.now();
document.getElementById('id');
t1 = performance.now();

console.log('Time to find element by ID: ' + (t1 - t0) + 'ms');
功能分区(el){
var div=document.createElement('div');
el.儿童组(分区);
返回div;
}
变量i,主体,el,t0,t1;
el=body=document.querySelector('body');

对于(i=0;除非您的用户正在使用Netscape,否则我认为您不必担心。我隐约记得IE6对哈希表的ID和名称相同存在问题,我认为IE5也使用了哈希表,所以这不是一个真正的问题。@adeneo-感谢遗留IE信息…谢谢-这也是一个具有可测试结果的很好答案!i notice在Chrome中,您可以有多个相同ID的实例,但它仍将应用一种样式(与W3标准相反?),但对于它将选择的元素,我需要进行测试……但我认为您已经回答了这个问题;)出于兴趣,这里可能会发生级联-因此它实际上找到的第一个是“BFS”,但搜索的最终结果是“DFS”-我不确定搜索是否会在第一个结果的位置停止,这当然会更快…有没有办法测试这一点?@user1360809请参阅我的帖子的编辑。它证明搜索会停止一段时间找到第一个ID匹配的元素后。哇!太棒了,先生,你应该得到一枚奖牌。我自己再做一个测试,稍后我会尝试-创建一个像你这样的单一集合(重嵌套+一个兄弟姐妹)但所有元素都有一个唯一的ID,然后搜索具有ID属性的项目并放入数组中-数组将按找到的元素的顺序列出。可能无法证明getElementById()的正确性它本身作为一种不同的搜索算法,可能用于查找具有属性的元素-一些比较可能是有序的…我可以使用getElementById()调用每个元素,并确定找到结果的速度,然后将结果放入有序数组中。。。