Code Fix #3: Toggling Classes with querySelectorAll

Code Fix #3: Toggling Classes with querySelectorAll

The difference between querySelector and querySelectorAll.

Welcome back! In this article, I'll be going over toggling classes with querySelectorAll.

Background

The person was given the HTML and CSS below:

<!-- index.html -->
<ul>
  <li>Hello</li>
  <li class="highlight">Hello</li>
  <li>Hello</li>
  <li class="highlight">Hello</li>
  <li>Hello</li>
  <li class="highlight">Hello</li>
</ul>
/* styles.css */
.highlight {
  background-color: #d09cd9;
}

Ouput

Screen Shot 2021-08-13 at 8.26.51 AM.png

The Task

The task was to toggle the class "highlight" among the <li> elements to change the output to this:

Screen Shot 2021-08-13 at 8.27.17 AM.png

The Problem

This person had the code below, which wasn't getting the expected results:

const items = document.querySelector("li");

for (let item of items) {
    item.classList.toggle("hidden");
}

Why It Doesn't Work

This is thankfully a simple fix!

The querySelector method returns only the first element that matches the specified selector.

const items = document.querySelector("li");
console.log(items); // <li>Hello</li>

Instead, querySelectorAll should be used, which grabs all elements that match and puts them into a NodeList - a collection of nodes in an array.

const items = document.querySelectorAll("li");
console.log(items); // NodeList (6), [<li>Hello</li>, <li class="highlight">Hello</li>...]

The Solution

There are different ways you can code this:

//Option 1 with a for...of loop
const items = document.querySelectorAll("li");

for (let item of items) {
    item.classList.toggle("highlight");
}

If you're not a fan of for...of loops, you'll get the same result with a regular for loop:

// Option 2 with a for loop
const items = document.querySelectorAll("li");

for (let i = 0; i <= items.length; i++) {
    items[i].classList.toggle("highlight");
}

Lastly, you can use the forEach method for arrays:

// Option 3 with forEach
const items = document.querySelectorAll("li");

items.forEach(item => item.classList.toggle("highlight");

I hope this helped. Feel free to check out the CodePen!

Do you have another way of doing this? Let me know in the comments!