querySelector vs. getElementById querySelector vs. getElementById

203
我听说querySelectorquerySelectorAll是选择DOM元素的新方法。就性能和浏览器支持而言,它们与旧方法getElementByIdgetElementsByClassName相比如何?
在性能方面,与使用jQuery的查询选择器相比如何? querySelectorgetElementById之间有什么区别? 何时应该使用querySelector而不是getElementById?是否有任何不可能使用getElementById的示例?

1
定义得更好。它们几乎完全不同。 - user1106925
5
这就像问“单一尺寸的板钳比可调板钳更好吗?”答案是:它们更强大、更灵活,在许多情况下更优越,但getElementByIdgetElementsByClassName仍然是它们名称描述的目的理想选择。 - lonesomeday
2
哦,而且 qS/qSA 可以在任何元素上下文中使用,但是 gEBI 只能在 document 上下文中使用。 - user1106925
5
getElementById 方法通过匹配 id 属性来查找 DOM 节点,而 querySelector 方法则通过选择器来搜索。因此,对于一个无效的选择器,例如 <div id="1"></div>getElementById('1') 将能够正常工作,而 querySelector('#1') 则会失败,除非你告诉它去匹配 id 属性(例如 querySelector('[id="1"]'))。 - Ismail
4
提醒一下,对于任何阅读此文的人,现在querySelectorquerySelectorAll已经完全得到支持。https://caniuse.com/#feat=queryselector - jarrodwhitley
显示剩余2条评论
2个回答

213
"Better" is subjective.
querySelector是较新的功能。
getElementById比querySelector更受支持(尽管在这个答案最初撰写后的几年里并不重要)。
querySelectorAll比getElementsByClassName更受支持,但querySelectorAll提供的是静态节点列表,而getElementsByClassName提供的是动态节点列表。
querySelector允许您查找无法用getElementById和getElementsByClassName表达的规则的元素。
您需要根据具体任务选择合适的工具。
(在上述内容中,对于querySelector,请阅读querySelector / querySelectorAll)。

12
querySelector支持情况:http://caniuse.com/#feat=queryselector - tazboy
7
很好的回答,这里还有一些基准测试 - angel.bonev
为什么querySelector在遍历HTML代码时盲目选择第一个匹配的元素,而不是进行广度优先搜索并选择最接近父元素深度的第一个匹配元素? - undefined

52

getElementByIdgetElementsByClassName函数非常具体,而querySelectorquerySelectorAll则更为详细。 我的猜测是它们实际上会有更差的性能。

此外,您需要检查目标浏览器对每个函数的支持情况。新的浏览器越高,缺乏支持或功能“有故障”的可能性就越大。


@thomas,你的链接挂了。有其他可用的链接吗? - user5508297
8
有几个存档版本:https://web.archive.org/web/20160108040024/http://jsperf.com/getelementbyid-vs-queryselector 但这个测试实际上非常古老(2010年),所以结果可能会因为更现代化的引擎而大不相同。 - thomas
9
存档页面实际上是动态的,并允许您在当前浏览器上重新运行测试。在我的浏览器上,据报道,querySelectorAll仍然比getElementById慢约37%(Chrome 71-https://vgy.me/TwGL3o.png)。值得注意的是,getElementById返回一个实时结果,这意味着如果更改DOM,则getElementByID获取的结果将反映更改(如果在范围内),而querySelectorAll返回的节点列表是快照,例如在调用时的情况下,结果不会反映对DOM的后续更改。 - W.Prins
nodelist...不是实时的,你能提供相关文档吗?@W.Prins这两种方法都返回“Element”类型。 - Maximilian Burszley
啊,我看到我打错了,对不起!我应该在我写"getElementByID"的地方写"getElementsByClassName",例如,它是getElementsByClassName(和类似的)返回一个实时结果集。确实,getElementsByClassName和querySelectorAll都返回一个NodeList,但在前者的情况下,它是实时的,而在后者的情况下,它是一个快照。 - W.Prins
在GetElementsByClassName的情况下,其实时性在此处描述:https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname。在其他地方(https://www.w3.org/TR/selectors-api/#queryselectorall)中写道:“querySelectorAll()方法返回的NodeList对象必须是静态的,而不是实时的([DOM-LEVEL-3-CORE],第1.1.1节)。对基础文档结构的后续更改不得反映在NodeList对象中。” - W.Prins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接