DEV Community

Jasterix
Jasterix

Posted on

querySelectorAll vs getElements

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
metruzanca profile image
Samuele Zanca

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)

Collapse
 
jasterix profile image
Jasterix

Thanks! This was a typo, but illustrated the point (getElement* has more room for error) beautifully

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

JSPerf would say the getElement's are more performant than querySelector's.

Collapse
 
hyftar profile image
Simon Landry

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.

Collapse
 
fasil profile image
fasil

Thanks, Waiting for maths for programming part 2.

Collapse
 
jasterix profile image
Jasterix

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)