Modern Javascript Selectors

Navigating the DOM in javascript used to be a pain. It involved typing out verbose method names like getElementById . Then Jquery came along and introduced people to the idea of parsing the DOM using the same selectors people were already used to from CSS. It turns out people really liked this idea. Jquery became immensely popular. In fact you will rarely come across a site in the wild not including Jquery. But times have changed.

Vanilla JavaScript has come a long way. In fact the core library has even taken a few pages from the Jquery playbook and implemented their own version of a CSS selector engine.


This function takes any css selector the same way the core Jquery function does.

But it doesn’t work entirely the same. querySelector only returns the first element matched, while the Jquery function will return an array of all the matching elements. This is useful since Jquery also provides methods like $.each and $.map to easily parse over large groups of elements.

But no worries. We also have the querySelectorAll method which will return all elements matching the given selector. This is much more useful but we’re not quite there yet.

While JavaScript does provide native map and forEach methods, these methods are attached to the Array object prototype. This means they can only be called on Arrays. While you’d rightfully be expecting querySelectorAll to return an array of elements, you’d be wrong. It instead, returns a “node list”. A node list is like an array- but less useful. You can’t call array methods on it without a little extra work.

A node list is not an array but nothing in javascript can get around being an object. So we can iterate over it as an object like so

var aNodeList = document.querySelectorAll('.items')
	         aNodeList[item] = 'changed'
		return aNodeList[item] = 'changed'

But that feels like a bit of a hack (and was really just an excuse to show you how to forEach over an object). A better way would be to pluck the methods we need directly off the prototypes of the Array object like so.

var aNodeList = document.querySelectorAll('.items'), function(item){
	}), function(item){

But it still feels a bit like a hack. And both of these methods will fail in older browsers. The absolute best and safest way to handle this is to simply convert the node list to an array. You can even build a small abstraction on top of the querySelectorAll method that takes care of this for you. This is the function that I use.

 var get = function(selector){
        var el = document.querySelectorAll(selector)
        //keeps the code from breaking if there is no instance of the selector
        if (el){
            var size = el.length
            if(size == 1){
                //if there is only one instance than just return it
                return el[0]
                var list = []
                // build an array from the node list -- this way is very fast
                for(var i = size; i--; list.unshift(el[i]));
                // return the array
                return list    

Now we have a get function that we can call from anywhere in our code like so


This makes selecting elements easy and gives us access to all the build in array methods, such as filter, map, forEach, every, and reduce. Enjoy!