by Jonathan Sexton

How to avoid frustration by choosing the right JavaScript selector

A quick guide on how selectors affect your code

“A beautiful sunset in a cloudy sky, casted above a calm ocean.” by Sebastien Gabriel on Unsplash

While working on a project, I ran into an issue in my code. I was attempting to define multiple HTML elements into a collection and then change those elements based on some preset conditions. I struggled for roughly four hours of coding time (across two days) debugging my code and trying to figure out why I wasn’t getting my desired outcome.

Turns out I had used document.querySelectorAll() to assign my elements to a variable, and then I was attempting to change those elements. The only problem is that particular JavaScript selector returns a static node list. Since it isn’t a live representation of the elements, I wasn’t able to change them later in my code.

Assumptions

In this article, I assume a few things to be true:

  • You are working in “plain or vanilla” JavaScript (no framework / library)
  • You have a basic understanding of JavaScript elements / selectors
  • You have a basic understanding of the DOM

The Nitty-gritty

In the event I have assumed too much, I have provided links to relevant material within the article that I hope will be helpful.

JavaScript is such a vast and rich ecosystem that it’s no surprise that there are many ways of accomplishing the same task. Depending on your task, the way it is accomplished matters to a certain degree.

You can dig a hole with your hands, but it’s much easier and more efficient to do it with a shovel.

To that end, I hope to “hand you a shovel” after you’ve read this article.

“A long-exposure shot of a group of people on a beach with children digging a deep hole” by Khürt Williams on Unsplash

Choosing the right tool for the job

I’ve had the question, “Which element selector should I use?” several times. Until now, I haven’t had much desire or need to learn the difference as long as my code produced the desired result. After all, what does the color of the taxi matter as long as it gets you to your destination safely and in a timely manner…right?

Let’s start with some of the ways to select DOM elements in JavaScript. There are more ways (I believe) to select elements, but the ones listed here are by far the most prevalent I’ve come across.

document.getElementById()

These will only ever return one (1) element because, by their nature, ID’s are unique and there can only be one (with the same name) on the page at a time.

It returns an object that matches the string passed into it. It returns null if no matching ID is found in your HTML.

Syntax example -> document.getElementById(‘main_content’)

Unlike some selectors that we’ll get to later in the article, there is no need for a # to denote element id.

document.getElementsByTagName()

Notice the “S” in elements — this selector returns multiples in an array-like structure known as an HTML collection — all of the document is searched including the root node (the document object) for a matching name. This element selector starts at the top of the document and continues down, searching for tags that match the passed-in string.

If you are looking to use native array methods you’re out of luck. That is, unless you convert the returned results into an array to iterate over them, or use the ES6 spread operator — both of which are beyond the scope of this article. But I wanted you to know it is possible to use array methods if you wish to.

Syntax example -> document.getElementsByTagName(‘header_links’). This selector also accepts p, div, body, or any other valid HTML tag.

document.getElementsByClassName()

Class name selector — again notice the “S” in elements — this selector returns multiples in an array-like structure known as an HTML collection of class names. It matches the passed-in string (can take multiple class names, although they are separated by a space), searches all of the document, can be called on any element, and only returns descendants of the passed in class.

Also, no . (period) is needed to denote class name

Syntax example -> document.getElementsByClassName(‘className’)

document.querySelector()

This selector will only ever return one (1) element.

Only the first element matching the passed-in string will be returned. If no matches for the provided string are found, null is returned.

Syntax example -> document.querySelector(‘#side_note’) or document.querySelector(‘.header_links’)

Unlike all of our previous examples, this selector requires a . (period) to denote class or an # (octothorp) to denote an ID and works with all CSS selectors.

document.querySelectorAll()

This selector returns multiples that match the passed-in string and arranges them into another array like structure known as a node list.

As with some of the previous examples, the node list cannot make use of native array methods like .forEach(). So if you want to use those, you must first convert the node list into an array. If you do not wish to convert, you can still iterate over the node list with a for…in statement.

The passed in string must match a valid CSS selector — id, class names, types, attributes, values of attributes, etc.

Syntax example -> document.querySelectorAll(‘.footer_links’)

Wrapping up

By choosing the right selector for your coding needs, you’ll avoid many of the pitfalls I’ve fallen into. It can be incredibly frustrating when your code doesn’t work, but by ensuring that your selector matches your situational needs, you’ll have no trouble “digging with your shovel” :)

Thank you for reading through this post. If you enjoyed it, please consider donating some claps to help others find it as well. I publish (actively managing my schedule to write more) related content on my blog. I’m also active on Twitter and am always happy to connect with other developers!