As the old adage goes– you can do a million things a million ways in JavaScript.
One of those million things is to select a JavaScript element. The main ways you're probably familiar with are by using:
- querySelector
- querySelectorAll
- getElementById
- getElementsByTagName
- getElementByClassName
- getElementsByName
The first difference is obviously breadth. While querySelector* can obviously select either the first or all matching elements, getElement* has at least four options across two conventions– getElement vs getElements.
The main difference (and the reason I wanted to write this blog) is that querySelectorAll and getElements* return different values.
querySelectorAll
- querySelectorAll returns a non-live NodeList containing one Element object for each element that matches at least one of the specified selectors or an empty NodeList in case of no matches. (MDN)
- This is great because you can treat this node list like any array and use array methods like
forEach()
.
Below is an example of what this would look like in practice:
let content = document.querySelectorAll(".content") // undefined
content // NodeList(3) [div.content, div.content, div.content]
content.forEach(node => console.log(1)) // 1, 1, 1
As you can see above, the return value of content
is an array containing three items.
getElements
- getElements*, on the other hand, returns a live HTMLCollection of found elements.(MDN)
- Though it has square brackets like the NodeList, it does not have access to array methods like
forEach()
.
let collection = document.getElementsByClassName("content") // undefined
collection // HTMLCollection(3) [div.content, div.content, div.content]
collection.forEach(x=> console.log(x))
VM1771:1 Uncaught TypeError: collection.forEach is not a function
at <anonymous>:1:12
For beginners, I would say– default to using querySelector and querySelectorAll because do will avoid some of the pitfalls I outlined above.
While writing this blog post I briefly looked up videos from my favorite YouTubers and this one seemed like a keeper.
Hope you find it helpful =)
Top comments (6)
Either a typo or a misconsception.
There is not "getElementByClassName"
The only "getElement" is getElementById. All others are "getElements*"
On a side note:
Generally you should be using getElement* as they are more performant and the vast majority of cases for selecting elements in modern js is to add event listeners to elements. QuerySelector's main benefit is being able to mix up classes, ids and tag names in their query. e.g. as a stupid example
document.querySelectorAll('div div div .row')
selects the location and join date of the author of this blog post. However more often than not you'll just be able to getElementsByClassName of the parent element. I'm sure querySelector has some niche use cases e.g. writing code to manipulate markup you didn't write and can't modify for whatever reason. But in general I've always been of the opinion that getElement* > querySelector.(you can for..of instead of forEach or you can Array.From(...).forEach)
Thanks! This was a typo, but illustrated the point (getElement* has more room for error) beautifully
JSPerf would say the
getElement
's are more performant thanquerySelector
's.While this is also my first train of thought, this is what I like to call a micro optimization. In most cases, it won't make a noticeable difference.
Thanks, Waiting for maths for programming part 2.
Hi Fasil, thanks for commenting. I'm a bit overwhelmed with the job hunt right now, so don't have as much time to do the hours of research for the article. But I will be posting part 2 in the next few weeks (early March)