querySelectorAll()与getElementsByClassName()的区别、性能对比及选型建议
Hey folks! Let's break down the key differences between these two DOM selectors, compare their performance, and figure out which one to reach for in your projects.
Core Differences
Return Type:
querySelectorAll()returns a static NodeList—think of this as a snapshot of matching elements at the time you call it. Any later changes to the DOM (like adding/removing elements with the target class) won't affect this collection.getElementsByClassName()returns a dynamic HTMLCollection. This collection automatically updates to reflect changes in the DOM, so if you add a new element with the target class later, it'll show up in the collection without you re-running the query.
Selector Flexibility:
querySelectorAll()supports the full range of CSS selector syntax. You can use complex selectors like.parent .child,div.example:nth-child(2), or even combine multiple classes and elements in one query.getElementsByClassName()only accepts class names (you can pass multiple class names separated by spaces, like"example secondary"), but it doesn't support any other CSS selector features—no combinators, no pseudo-classes, nothing fancy.
Invocation Scope:
- Both can be called on any DOM element (not just
document), butquerySelectorAll()'s flexibility means you can narrow down searches with complex selectors starting from a parent element. For example:document.querySelector('.container').querySelectorAll('.item.active'). getElementsByClassName()called on a parent element will only search that element's descendants for matching class names, but again, it's limited to just class name matching.
- Both can be called on any DOM element (not just
Performance Comparison
In most cases, getElementsByClassName() is faster than querySelectorAll(), especially when dealing with large numbers of elements or frequent DOM operations. Here's why:
- The dynamic HTMLCollection is a live reference to the DOM, so it doesn't require creating a full copy of all matching elements upfront.
querySelectorAll()creates a static snapshot, which involves gathering all matching elements and storing them in a new NodeList—this adds a bit of overhead.
That said, for small-scale DOM queries (like selecting a handful of elements), the performance difference is negligible. You'll only notice it in performance-critical scenarios, like building data-heavy interfaces or handling thousands of DOM elements.
When to Use Which
Choose
querySelectorAll()if:- You need to use complex CSS selectors (combinators, pseudo-classes, etc.)
- You want a static collection that won't change as the DOM updates (prevents bugs where a live collection changes mid-traversal)
- You prefer a consistent selector syntax across your code (since it uses standard CSS selectors)
Choose
getElementsByClassName()if:- You only need to select elements by class name(s)
- You want a live collection that automatically syncs with DOM changes (no need to re-query when elements are added/removed)
- You're working on a performance-sensitive application where every bit of speed counts
Example Code
querySelectorAll() Implementation
JavaScript
function funDOM() { var x = document.querySelectorAll(".example"); var i; for (i = 0; i < x.length; i++) { x[i].style.backgroundColor = "red"; } }
HTML
<html> <body onload="funDOM()"> <div> Doubts <span class="example">red</span> </div> <p class="example">red</p> </body> </html>
getElementsByClassName() Implementation
JavaScript
function funDOM() { var x = document.getElementsByClassName("example"); var i; for (i = 0; i < x.length; i++) { x[i].style.backgroundColor = "red"; } }
HTML
<html> <body onload="funDOM()"> <div> Doubts <span class="example">red</span> </div> <p class="example">red</p> </body> </html>
内容的提问来源于stack exchange,提问作者alxwca

