【问题标题】:How does document.getElementById() search the DOM tree?document.getElementById() 如何搜索 DOM 树?
【发布时间】:2015-08-02 23:23:18
【问题描述】:

我知道一些浏览器(今天大多数?)为所有具有 ID 的元素创建一个哈希表。所以在这种情况下,对 document.getElementById() 的调用可以只搜索哈希表。但是在 DOM 树的上下文中,它将如何做到这一点 - 例如,它是深度优先搜索吗?

我问是因为我想知道放置 DOM 元素最快的位置在哪里,所以它会在搜索本身开始时立即或接近搜索时找到。

快速浏览了一下,没有找到关于这个主题的任何信息。

非常感谢任何帮助。

【问题讨论】:

  • 除非您的用户使用 Netscape,否则我认为您不必担心这一点。我记得模糊地 IE6 的哈希表对于 ID 和名称是相同的,我认为 IE5 也使用了哈希表,所以这不是一个真正的问题。
  • @adeneo - 感谢旧版 IE 信息...

标签: javascript html performance dom search


【解决方案1】:

由于 DOM 实现依赖于浏览器,每个浏览器都可能以不同的方式实现它。浏览器也有可能拥有所有 ID 的哈希映射并使用它执行document.getElementById

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

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

HTML

<div>
  <div id="id" data-index="DFS"></div>
</div>
<div id="id" data-index="BFS"></div>

JavaScript

console.log(document.getElementById('id').getAttribute('data-index'));

控制台输出

DFS

Plunker

http://plnkr.co/edit/jaUolyxwrZcXsNXwkmtm?p=preview

编辑:

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

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

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

JavaScript

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

http://plnkr.co/edit/jmGRJvq0qB7qMyyMULhz?p=info

【讨论】:

  • 谢谢 - 这也是一个很好的答案,结果也可测试!我注意到在 Chrome 中你可以有多个相同 ID 的实例,它仍然会应用一种样式(与 W3 标准相反?)但至于它将选择哪个元素我需要测试......但我认为你已经回答了这个一个已经;)
  • 出于兴趣,这里可能会发生级联 - 所以它实际上找到的第一个是'BFS',但搜索的最终结果是'DFS' - 我不确定搜索是否会停止在第一个结果的位置,当然会更快......有没有办法测试这个?
  • @user1360809 查看我的帖子的编辑。证明在找到第一个匹配 ID 的元素后停止搜索。
  • 哇!太棒了,先生,您应该获得奖牌。
  • 有另一个我自己的测试,我稍后会尝试 - 创建一个像你一样的单一集合(高度嵌套 + 一个兄弟),但都有一个唯一的 ID,然后搜索具有 ID 的项目属性并放入一个数组 - 该数组将按其找到的元素的顺序列出。可能无法证明 getElementById() 本身作为一种不同的搜索算法可能用于查找具有属性的元素 - 一些比较可能是有序的......我可以用 getElementById() 调用每个元素,并确定找到结果的速度然后放入一个有序的数组可能......
猜你喜欢
  • 2015-01-14
  • 2021-12-24
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2013-09-19
  • 2010-10-04
相关资源
最近更新 更多