Better JavaScript Element Selection with querySelector

One of the best features of jQuery is the simplified element selection which allows us to select DOM items as we select it in CSS (often it can be more complex). Now it is broadly available in plain JavaScript with the use of querySelector(All) functions.

Better JavaScript Element Selection with querySelector article's cover image

Old style element selection in Javascript

In JS you had three methods to select DOM elements: getElementById(), getElementsByClassName(), getElementsByTagName().

These selectors work almost in all old browsers.

getElementById()

You can access the element by id. It is the fastest selection type, but it has a significant limitation which is that you – as the name says – can select just id and mostly there is only one in your document by name.

var el = document.getElementById('bar');
 el.innerHTML = 'Hello World!';

getElementsByClassName()

The getElementsByClassName() method returns an element collection by the given class name. It is supported in the modern browsers back to IE 9. You get back a NodeList so you have to itarate trough the result e.g. with a for loop like in the following example:

var classElements = document.getElementsByClassName('bar');

for (var i=0; i<classElements.length; i++) {
    console.log(classElements[i].innerHTML);
}

I think the biggest pitfall of this selection method is that you have to filter the results if you like to select by more accurate terms.

You can find more iteration example below.

getElementsByTagName()

This method works similar like the getElementsByClassName() but it selects the elements by tag name (like <span>, <div>) instead of class. You also get back a NodeList. It widely supported.

var tagNameElements = document.getElementsByTagName('span');

for (var i=0; i<tagNameElements.length; i++) {
    console.log(tagNameElements[i].innerHTML);
}

querySelector(All) for the rescue

As I mentioned previously that jQuery CSS-alike selector feature one of the best features of the framework, this is mostly indubitable.

Now with the use of querySelector() and querySelectorAll() method you can select elements like you do it in jQuery or CSS.

querySelector() method

This method gives back the first result of the given selector which could be anything – except pseudo-class and element – that works in CSS.

var divs = document.querySelectorAll([data-id="3"]);

querySelectorAll() method

The method give back a non-live NodeList. You can give multiple selectors with the use of comma.

var matches = document.querySelectorAll("div.note, div.alert"); 

[].forEach.call(matches , function(match) {
    match.style.color = "blue";
});

When you use the querySelector(All) methods be aware of the followings:

  • If there is no result, you get back null.
  • The selector must be a valid CSS selector.
  • The querySelector() was introduced in the Selectors API.
  • The querySelectorAll() was introduced in the WebApps API.
  • You cant select pseudo-class or element.

Iteration techniques

There are more methods to iterate NodeLists in JavaScript.

For loop

This is the easiest and most time the fastest method. You use a standard, generic for loop.

var divs = document.querySelectorAll('div');

for (var i = 0; i < divs.length; ++i) {
    divs[i].style.color = "blue";
}

ForEach with call

This technique is my favorite. It is a little bit slower than the for loop but it is more elegant. With the help of call, we can you the array’s forEach method.

var divs = document.querySelectorAll('div');

[].forEach.call(divs, function(div) {
    div.style.color = "blue";
});

ForEach loop

Important to note that the NodeList is not array though it is look alike. Mostly this means that you can’t use forEach on a NodeList, but nowadays in the newer browsers you can use an each loop on a NodeList, but this is a quite new feature.