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
The Task
The task was to toggle the class "highlight" among the <li>
elements to change the output to this:
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!