题 JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById


我想知道究竟是什么区别 querySelector 和 querySelectorAll 反对 getElementsByClassName 和 getElementById

这个链接 我可以收集它 querySelector 我可以写 document.querySelector(".myclass") 用类来获取元素 myclass 和 document.querySelector("#myid") 获取带ID的元素 myid。但我已经可以做到了 getElementsByClassName 和 getElementById。应该首选哪一个?

我也在工作 的XPages 其中ID是使用冒号动态生成的,如下所示 view:_id1:inputText1。所以当我写作 document.querySelector("#view:_id1:inputText1") 它不起作用。但写作 document.getElementById("view:_id1:inputText1") 作品。有什么想法吗?


105
2018-01-17 11:00


起源


querySelector用于查询HTML DOM树,它可以包含h​​tml元素及其属性作为查询的关键元素...你可以使用正则表达式实现这一点.. dojo.query()做同样的事情 - anix
不是吗? document.querySelectorAll(".myclass")?运用 document.querySelector(".myclass") 只会返回匹配的第一个元素。 - mhatch


答案:


我想知道querySelector和querySelectorAll对getElementsByClassName和getElementById的区别究竟是什么?

语法和浏览器支持。

querySelector 当您想要使用更复杂的选择器时更有用。

例如所有列表项都来自作为foo类成员的元素: .foo li

document.querySelector(“#view:_id1:inputText1”)它不起作用。但是编写document.getElementById(“view:_id1:inputText1”)可以正常工作。有什么想法吗?

: 字符在选择器中具有特殊含义。你必须逃脱它。 (选择器转义字符在JS字符串中也有特殊含义,因此您必须转义  太)。

document.querySelector("#view\\:_id1\\:inputText1")

72
2018-01-17 11:01



关于性能的任何想法,哪个更好? - Naveen
它会因浏览器而异(从版本到版本)。我认为基于选择器的那些更昂贵(但不会以一种可能非常重要的方式) - Quentin
@Naveen:您能否添加JSPerf的总结结论,而不仅仅是链接?例如,该网站今天已经关闭,我想知道如何比较课程的性能。谢谢! - jtheletter
我支持@ janaspage的声明。网站今天也在下降。 - doplumi
关于课程选择也参见 jsperf.com/getelementsbyclassname-vs-queryselectorall/25。结论:一个人应该更喜欢纯javascript而不是jquery,以及具体的功能 getElementById 和 getElementsByClassName。 className选择可能很少 数以百计 没有时间慢 getElementsByClassName。 - Atrahasis


从中收集 Mozilla文档:

NodeSelector接口 此规范为实现Document,DocumentFragment或Element接口的任何对象添加了两个新方法:

querySelector

返回 第一个匹配的Element节点 在节点的子树中。如果   找不到匹配的节点,返回null。

querySelectorAll

返回一个 包含所有匹配元素的NodeList 内部的节点   节点的子树,如果没有找到匹配则为空的NodeList。

注意:返回的NodeList querySelectorAll() 不是活的,哪个   表示DOM中的更改未反映在集合中。   这与返回实时的其他DOM查询方法不同   节点列表。


58
2017-11-05 12:49



+1用于指出实时节点列表的区别。根据您打算如何使用结果,这是一个非常重要的区别。 - jmbpiano
什么“不活”意味着......谢谢 - dsdsdsdsd
“live”表示在DOM运行时添加的节点,可以在newley添加的节点上运行 - diEcho


关于差异,结果之间有一个重要的区别 querySelectorAll 和 getElementsByClassName:返回值不同。 querySelectorAll 将返回一个静态集合 getElementsByClassName 返回实时收藏。如果将结果存储在变量中供以后使用,这可能会导致混淆:

  • 生成的变量 querySelectorAll 将包含满足选择器的元素 此时该方法被调用
  • 生成的变量 getElementsByClassName 将包含满足选择器的元素 当它被使用 (可能与调用方法的时刻不同)。

例如,请注意即使您没有重新分配变量 aux1 和 aux2,它们在更新类后包含不同的值:

// storing all the elements with class "blue" using the two methods
var aux1 = document.querySelectorAll(".blue");
var aux2 = document.getElementsByClassName("blue");

// write the number of elements in each array (values match)
console.log("Number of elements with querySelectorAll = " + aux1.length);
console.log("Number of elements with getElementsByClassName = " + aux2.length);

// change one element's class to "blue"
document.getElementById("div1").className = "blue";

// write the number of elements in each array (values differ)
console.log("Number of elements with querySelectorAll = " + aux1.length);
console.log("Number of elements with getElementsByClassName = " + aux2.length);
.red { color:red; }
.green { color:green; }
.blue { color:blue; }
<div id="div0" class="blue">Blue</div>
<div id="div1" class="red">Red</div>
<div id="div2" class="green">Green</div>


45
2017-08-29 18:58



只是提一下 - 所有旧的DOM apis都返回一个节点列表 document.getElementsByName, document.getElementsByTagNameNS 要么 document.getElementsByTagName 将表现出相同的行为。 - RBT
一些分析表明querySelector比getElementById需要更多的时间,就像这里一样 dimlucas.com/index.php/2016/09/17/... 。如果我们考虑访问时间怎么办?从getElementById获取的活动节点比querySelector中的静态节点花费更多时间吗? - Eric


querySelector 可以是一个完整的CSS(3) - 具有ID和类和伪类的选择器,如下所示:

'#id.class:pseudo'

// or

'tag #id .class .class.class'

getElementByClassName 你可以定义一个类

'class'

getElementById你可以定义一个id

'id'

15
2018-01-17 11:03



是 :first 现在是一个CSS选择器? :first-class, 要么 :first-of-type 也许,但我想 :first 是一个JavaScript / jQuery / Sizzle的补充。 - David Thomas
我只是想告诉你,那 :pseudo-syntax 是可能的 - algorhythm
@DavidThomas是的,它是CSS3的一部分。它可以像这样使用: css-tricks.com/almanac/selectors/f/first-child - algorhythm
但 :first 显然不是 :first-child。 - David Thomas
“作者被告知,虽然允许在选择器中使用伪元素,但它们不会匹配文档中的任何元素,因此不会导致返回任何元素。因此,建议作者避免使用伪 - 选择器中传递给本规范中定义的方法的元素。“ w3.org/TR/selectors-api/#grammar - rich remer


我来到这个页面纯粹是为了找出在性能方面使用的更好的方法 - 即哪个更快:

querySelector / querySelectorAll or getElementsByClassName

我发现了这个: https://jsperf.com/getelementsbyclassname-vs-queryselectorall/18

它对上面的2个例子进行了测试,并且还测试了jQuery的等效选择器。我的测试结果如下:

getElementsByClassName = 1,138,018 operations / sec - <<< clear winner
querySelectorAll = 39,033 operations / sec
jquery select = 381,648 operations / sec

9
2018-05-14 19:23





querySelector 和 querySelectorAll 是一个相对较新的API,而 getElementById 和 getElementsByClassName 我们已经和我们待了很长时间。这意味着您使用的内容主要取决于您需要支持哪些浏览器。

至于 :,它具有特殊含义,因此如果必须将其用作ID /类名称的一部分,则必须将其转义。


6
2018-01-17 11:03



关于性能的任何想法,哪个更好? - Naveen
这不一定是真的。例如, querySelectorAll 在IE8中可用,而 getElementsByClassName 不是。 - DaveJ
querySelectorAll ...基本上一切: caniuse.com/#search=querySelectorAll - dsdsdsdsd
@Naveen getelementsbyclassname vs querySelectorAll vs jquery select 可能会有所帮助。 - lowtechsun