28

我想知道在 JavaScript 中选择元素的两种不同语法。

假设如果我想从当前文档中选择所有 div,那么:

var divs = document.getElementsByTagName("div");
console.log("There are "+divs.length+" Divs in Document !");

会正常工作。但是还有另一种方法,例如:

var divs = document.querySelectorAll("div");
console.log("There are "+divs.length+" Divs in Document !");

当它们都以相同的方式工作时。他们之间有什么区别?

  • 哪个更快?
  • 为什么?
  • 两者如何运作?
  • 提前致谢。我见过这样的问题,但他们没有满足需求。

    4

    7 回答 7

    44

    大多数答案都是错误的。Nicolae Olariu 是唯一一个正确回答的人

    哪个更快?为什么?

    不是问题。真正的问题“它是如何工作的?”

    主要区别在于此示例:

    <!doctype html> 
    <html> 
    <head> 
        <meta charset="utf-8"> 
        <title>Yandex</title> 
    
    </head> 
    <body> 
        <a href="((http://yandex.ru))">Яндекс</a>, 
        <a href="((http://yandex.com))">Yandex</a> 
    </body> 
    <script>
    
    var elems1 = document.getElementsByTagName('a'), // return 2 lements, elems1.length = 2 
        elems2 = document.querySelectorAll("a");  // return 2 elements, elems2.length = 2 
    
    document.body.appendChild(document.createElement("a")); 
    
    console.log(elems1.length, elems2.length);  // now elems1.length = 3! 
                                                // while elems2.length = 2
    </script>
    </html> 
    

    因为 querySelectorAll 返回一个静态(非实时)元素列表。

    于 2015-06-18T17:05:46.693 回答
    24

    选择

    getElementsByTagName仅根据标签名称选择元素。querySelectorAll可以使用任何选择器,使其具有更大的灵活性和功能。

    返回值

    • gEBTN 返回一个活动节点列表。
    • qSA 返回一个静态节点列表。

    实时节点列表可能很有用(您可以查询一次,存储值,并随着 DOM 的变化而更新),但会造成很多混乱,例如这个问题中的示例。

    通常静态列表更容易处理。

    支持

    gEBTNqSA参见caniuse 。

    gEBTN 有更多支持,但 qSA 在与当今大多数用例相关的所有浏览器中都有支持。

    表现

    你可能不应该在意。这些函数不太可能成为代码中的瓶颈。

    我已经看到关于哪个更快的相互矛盾的报告。无论如何,它可能因浏览器而异。

    于 2013-08-15T06:20:20.393 回答
    9

    来自 MDN:

      element = document.querySelector(选择器);  

    返回文档中与指定选择器组匹配的第一个元素(使用文档节点的深度优先前序遍历)。

      元素 = element.getElementsByTagName(tagName) 

    返回具有给定标签名称的元素列表。搜索指定元素下的子树,不包括元素本身。返回的列表是实时的,这意味着它会自动使用 DOM 树进行自我更新。因此,无需使用相同的元素和参数多次调用 element.getElementsByTagName。

    于 2013-08-15T06:20:29.707 回答
    1

    querySelector还支持其他 CSS 选择器,例如"#id"通过 id 获取元素,以及"input[type=text]"获取具有type=text属性的所有输入元素。有关更多详细信息,请参见此处

    对于像您询问的那样的简单查询,它们可能同样快,但对于高级 CSS 选择器,使用起来可能比自己应用一些手动过滤要快得多(更不用说要编写的代码少得多)querySelectorAll,这就是库的原因就像querySelectorAll浏览器支持时使用 jQuery 一样。

    于 2013-08-15T06:21:47.093 回答
    1

    这是一个关于 querySelector 和 getElementsByTagName 之间区别的示例。

    在这个例子中,作者选择querySelector解决问题。

    getElementsByTagName 还返回一个活动的 nodeList,当我们将链接附加到内存中的无序列表时,链接会从文档中删除,并且集合的长度会受到影响。

    所以

    if(you don't want to change the NodeList during the follow-up script work){
        "use querySelectorAll"}
    else if(you want to change the NodeList during the follow-up script work) {
        "use getElementsByTagName" 
    }
    

    你可以尝试getElementsByTagName在这个例子中使用,你会发现它不起作用。

    于 2017-09-15T12:58:24.327 回答
    0

    选择器

    除了另一个答案中已经涵盖的返回值之外,另一个关键区别是getElementBy*TagName(或 - Id- Class)和 querySelector/querySelectorAll 是后者接受选择器,而其他选择器是标签、id 或类。使用 querySelector() 您可以执行以下操作:

    document.querySelectorAll('p.my16')
    

    这是不可能的getElementByTagName

    为每个

    如果需要对getElements*函数的结果进行 foreach,一个简单的技巧(传播)将允许这样做。

    [...document.getElementsByClassName('my16')].forEach(e=>console.log(`hallo ${e}`))
    

    顺便提一句。我同意海报的表现是高度无关的。专注于手头的用例是有意义的。

    于 2022-01-14T10:44:12.220 回答
    -1

    在这个例子中:

    <html> 
    <head> 
        <meta charset="utf-8"> 
        <title>Yandex</title> 
    </head> 
    <body> 
        <a href="((http://yandex.ru))">Яндекс</a>, 
        <a href="((http://yandex.com))">Yandex</a> 
    </body> 
    <script>
        var elems1 = document.getElementsByTagName('a'), // return 2 lements, elems1.length = 2 
        elems2 = document.querySelectorAll("a");  // return 2 elements, elems2.length = 2 
    
        document.body.appendChild(document.createElement("a")); 
    
        console.log(elems1.length, elems2.length);  // now elems1.length = 3! 
                                                    // while elems2.length = 2
    </script>
    </html>
    

    创建的元素放在 script 标签之后,不能被querySelector. 只有getElementsByTagName才能找到新元素。

    于 2018-10-26T19:58:21.087 回答