In JavaScript der Unterschied zwischen querySelector und querySelectorAll sowie getElementsByClassName und getElementById
P粉442576165
P粉442576165 2023-08-21 21:45:39
0
2
540

Ich möchte wissen, was der Unterschied zwischen querySelector und getElementsByClass ist. Code> Was ist der Unterschied?

Über diesen Link habe ich erfahren, dass ich mit querySelector document.querySelector(".myclass") schreiben kann, um die Datei mit dem Klassennamen< ;code>myclass und document.querySelector("#myid"), um das Element mit der ID myid abzurufen. Aber ich kann diese Funktionalität bereits mit getElementsByClassName und getElementById erreichen. Welches sollte bevorzugt werden?

Außerdem arbeite ich in XPages und die IDs werden dynamisch generiert, enthalten Doppelpunkte und sehen so aus: view:_id1:inputText1. Wenn ich also document.querySelector("#view:_id1:inputText1") schreibe, funktioniert es nicht. Aber wenn ich document.getElementById("view:_id1:inputText1") schreibe, funktioniert es. Irgendwelche Ideen, warum das passiert?

P粉442576165
P粉442576165

Antworte allen (2)
P粉008829791

对于这个答案,我将querySelectorquerySelectorAll称为querySelector*,将getElementByIdgetElementsByClassNamegetElementsByTagNamegetElementsByName称为getElement*。

这些信息的很多可以在规范中进行验证,很多是我在编写时运行的各种基准测试得出的。规范:https://dom.spec.whatwg.org/

主要区别

  1. querySelector*更灵活,因为您可以传递任何CSS3选择器,而不仅仅是简单的id、tag或class。
  2. querySelector*的性能随其调用的DOM的大小而变化。准确地说,querySelector*调用以O(n)时间运行,而getElement*调用以O(1)时间运行,其中n是调用所在元素或文档的所有子元素的总数。
  3. 这些调用的返回类型有所不同。querySelectorgetElementById都返回单个元素。querySelectorAllgetElementsByName都返回NodeList。getElementsByClassNamegetElementsByTagName都返回HTMLCollection。NodeList和HTMLCollection都被称为元素的集合。
  4. 集合可以分别返回“live”或“static”集合。这在它们返回的实际类型中没有反映出来。getElements*调用返回live集合,而querySelectorAll返回static集合。据我理解,live集合包含对DOM中元素的引用,而static集合包含元素的副本。您还可以查看下面的@Jan Feldmann的评论,以获取不同的角度。我还没有找到一个好的方法将其纳入我的答案,但它可能是一个更准确的理解。

这些概念在下表中总结。

Function | Live? | Type | Time Complexity querySelector | | Element | O(n) querySelectorAll | N | NodeList | O(n) getElementById | | Element | O(1) getElementsByClassName | Y | HTMLCollection | O(1) getElementsByTagName | Y | HTMLCollection | O(1) getElementsByName | Y | NodeList | O(1)

详细信息、提示和示例

  • HTMLCollection不像NodeList那样类似于数组,不支持.forEach()。我发现扩展运算符对绕过这个问题很有用:

    [...document.getElementsByClassName("someClass")].forEach()

  • 每个元素和全局document都可以访问所有这些函数,除了getElementByIdgetElementsByName,它们只在document上实现。

  • 链式使用getElement*调用而不是使用querySelector*将提高性能,特别是在非常大的DOM上。即使在小的DOM和/或非常长的链上,通常也更快。然而,除非您知道需要性能,否则应该优先选择querySelector*的可读性。querySelectorAll通常更难重写,因为您必须在每一步中从NodeList或HTMLCollection中选择元素。例如,以下代码不起作用

    document.getElementsByClassName("someClass").getElementsByTagName("div")

    因为您只能在单个元素上使用getElements*,而不是集合,但如果您只想要一个元素,那么:

    document.querySelector("#someId .someClass div")

    可以写成:

    document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]

    注意在返回集合的每一步中使用[0],以获取集合的第一个元素,最终结果只有一个元素,就像使用querySelector一样。

  • 由于所有元素都可以使用querySelector*和getElement*调用,因此可以同时使用这两个调用进行链式操作,这在您想要一些性能提升但无法避免使用无法用getElement*调用编写的querySelector时非常有用。

  • 尽管通常很容易判断一个选择器是否可以只使用getElement*调用来编写,但有一种情况可能不明显:

    document.querySelectorAll(".class1.class2")

    可以重写为

    document.getElementsByClassName("class1 class2")

  • 在使用querySelector*获取的静态元素上使用getElement*将导致元素相对于querySelector复制的静态DOM子集是动态的,但相对于完整文档DOM是静态的...这就是简单的动态/静态元素解释开始分崩离析的地方。您应该尽量避免需要担心这个问题的情况,但如果确实存在这种情况,请记住querySelector*调用在返回引用之前会复制它们找到的元素,而getElement*调用则会直接获取引用而不复制。

  • querySelector*和getElementById以前序、深度优先的方式遍历元素,在规范中称为“树顺序”。对于其他getElement*调用,从规范中我无法确定它们是否与树顺序相同,但getElementsByClassName(".someClass")[0]可能在每个浏览器中结果不可靠。getElementById("#someId")应该是可靠的,即使您的页面上有多个相同的id副本。

  • 当我在处理无限滚动页面时,我不得不研究这个问题,我认为这可能是一个常见的情况,性能成为一个问题。我们的代码中有onScroll事件,其中包含querySelectorAll调用。即使调用被限制速率,如果您滚动到足够远的位置,页面也会崩溃,此时将有太多调用迭代太多元素,浏览器无法跟上。DOM的大小在这种用例中是相关的,因此在无限滚动页面上运行的代码中,更倾向于使用getElement*调用。

    P粉238355860

    语法和浏览器支持。

    querySelector在你想要使用更复杂的选择器时更有用。

    例如,所有从属于foo类的元素的列表项:.foo li

    :字符在选择器中有特殊含义。你需要对它进行转义。(选择器转义字符在JS字符串中也有特殊含义,所以你也需要转义)。

    document.querySelector("#view\\:_id1\\:inputText1")
      Neueste Downloads
      Mehr>
      Web-Effekte
      Quellcode der Website
      Website-Materialien
      Frontend-Vorlage
      Über uns Haftungsausschluss Sitemap
      Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!