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

从这个链接,我可以用querySelector收集,我可以写document.querySelector(".myclass")来获得类myclass的元素,文档.querySelector("#myid")来获得ID为myid的元素。但我已经可以做到getElementsByClassName和getElementById。应该优先选择哪一种?

我还在XPages中工作,其中ID是用冒号动态生成的,类似于以下视图:_id1:inputText1。所以当我写document.querySelector(“#view:_id1:inputText1”)时,它不起作用。但是写document.getElementById("view:_id1:inputText1")是有效的。知道为什么吗?


当前回答

看看这个

https://codepen.io/bagdaulet/pen/bzdKjL

getElementById比querySelector快25%

Jquery是最慢的

var q = time_my_script(function() {

    for (i = 0; i < 1000000; i++) {
         var w = document.querySelector('#ll');
    }

});

console.log('querySelector: '+q+'ms');

其他回答

querySelector和querySelectorAll是一个相对较新的api,而getElementById和getElementsByClassName已经和我们在一起很长时间了。这意味着您使用什么主要取决于您需要支持的浏览器。

至于:,它有一个特殊的含义,所以如果你必须将它用作ID/类名的一部分,你必须转义它。

querySelector可以是一个完整的CSS(3)-Selector,包括id、类和伪类,如下所示:

'#id.class:pseudo'

// or

'tag #id .class .class.class'

使用getElementsByClassName,你可以定义一个类

'class'

使用getElementById,你可以只定义一个id

'id'

querySelector和querySelectorAll的区别

//querySelector返回单个元素 let listsingle = document.querySelector('li'); console.log (listsingle); //querySelectorAll返回点亮的/数组元素 let list = document.querySelectorAll('li'); console.log(列表); //注意:输出将在Console中可见 < ul > <李类= >“测试”飞行符李< / > <李类=“测试”> vvvv李< / > <李> dddd李< / > <李类=“测试”> ddff李< / > < / ul >

从Mozilla文档收集:

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

querySelector

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

querySelectorAll

对象中所有匹配的Element节点 节点的子树,如果没有找到匹配则返回空的NodeList。

and

注意:querySelectorAll()返回的NodeList不是活的 意味着DOM中的更改不会反映在集合中。 这与返回live的其他DOM查询方法不同 节点列表。

对于这个答案,我将querySelector和querySelectorAll作为querySelector*,并将getElementById, getElementsByClassName, getElementsByTagName和getElementsByName作为getElement*。

很多信息都可以在规范中得到验证,其中很多都来自我编写规范时运行的各种基准测试。规范:https://dom.spec.whatwg.org/

主要区别

querySelector* is more flexible, as you can pass it any CSS3 selector, not just simple ones for id, tag, or class. The performance of querySelector* changes with the size of the DOM that it is invoked on. To be precise, querySelector* calls run in O(n) time and getElement* calls run in O(1) time, where n is the total number of all children of the element or document it is invoked on. The return types of these calls vary. querySelector and getElementById both return a single element. querySelectorAll and getElementsByName both return NodeLists. The older getElementsByClassName and getElementsByTagName both return HTMLCollections. NodeLists and HTMLCollections are both referred to as collections of elements. Collections can return "live" or "static" collections respectively. This is NOT reflected in the actual types that they return. getElements* calls return live collections, and querySelectorAll returns a static collection. The way that I understand it, live collections contain references to elements in the DOM, and static collections contain copies of elements. Take a look at @Jan Feldmann's comment's below for a different angle as well. I haven't figured out a good way to incorporate it into my answer but it may be a more accurate understanding.

下表总结了这些概念。

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)

细节,提示和示例

HTMLCollections are not as array-like as NodeLists and do not support .forEach(). I find the spread operator useful to work around this: [...document.getElementsByClassName("someClass")].forEach() Every element, and the global document, have access to all of these functions except for getElementById and getElementsByName, which are only implemented on document. Chaining getElement* calls instead of using querySelector* will improve performance, especially on very large DOMs. Even on small DOMs and/or with very long chains, it is generally faster. However, unless you know you need the performance, the readability of querySelector* should be preferred. querySelectorAll is often harder to rewrite, because you must select elements from the NodeList or HTMLCollection at every step. For example, the following code does not work: document.getElementsByClassName("someClass").getElementsByTagName("div") because you can only use getElements* on single elements, not collections, but if you only wanted one element, then: document.querySelector("#someId .someClass div") could be written as: document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0] Note the use of [0] to get just the first element of the collection at each step that returns a collection, resulting in one element at the end just like with querySelector. Since all elements have access to both querySelector* and getElement* calls, you can make chains using both calls, which can be useful if you want some performance gain, but cannot avoid a querySelector that can not be written in terms of the getElement* calls. Though it is generally easy to tell if a selector can be written using only getElement* calls, there is one case that may not be obvious: document.querySelectorAll(".class1.class2") can be rewritten as document.getElementsByClassName("class1 class2") Using getElement* on a static element fetched with querySelector* will result in an element that is live with respect to the static subset of the DOM copied by querySelector, but not live with respect to the full document DOM... this is where the simple live/static interpretation of elements begins to fall apart. You should probably avoid situations where you have to worry about this, but if you do, remember that querySelector* calls copy elements they find before returning references to them, but getElement* calls fetch direct references without copying. querySelector* and getElementById traverse elements in preorder, depth-first, called "tree order" in the specification. With other getElement* calls it is not clear to me from the specification - they may be the same as tree order, but getElementsByClassName(".someClass")[0] may not reliably give the same result in every browser. getElementById("#someId") should though, even if you have multiple copies of the same id on your page. I was working on an infinite scroll page when I had to look into this, and I think that is likely to be a common case where performance becomes an issue. Our code had onScroll events with querySelectorAll calls in them. Even if the calls were rate limited, the page would break if you scrolled down far enough, at which point there would be too many calls iterating through too many elements for the browser to keep up. The size of the DOM is relevant in this use case, and so there's a good case for preferring getElement* calls in code that runs on an infinite scroll page.