Adding a class on an event works great for making a navigation active or communicating between parts of your application. Using the JavaScript selector, forloop and event methods are what is needed to make this happen.

Document: querySelectorAll() method

The selector method querySelectorAll returns a list of document elements. So if we have a div with a bunch of buttons and do:

<div class="example">
<button class="btn">1</button>
<button class="btn active">2</button>
<button class="btn">3</button>
<button class="btn">4</button>
</div>
let buttons = document.querySelectorAll('.btn');

The console.log(buttons); should get back a NodeList of all the buttons.

screenshot of NodeList

Although the querySelectorAll() method does no work for dynamically changed evens. So for example if you are creating a list of elements and at some point after the HTML document has been parsed in your page, you will not be able to access these elements with querySelectorAll(). Instead use event delegation and set the querySelector on the parent element. Then use the children property to return a live HTMLCollection which contains all of the child elements. You can see an example of this on my Loop Through CSS Animations post.

Array.prototype.forEach()

Now we can attach the button NodeList to a forEach loop and do something.

In combination with the forEach() method we can execute a function once for each element in the array.

addEventListener()

Here we will add an addEventListener with a click event. This will be a two step process where first, we remove all the active classes from the button, then we apply the active class to the specific button we clicked.

Using an addEventListener method we can add and remove an active class on click.

The addEventListener is a EventTarget that listens for events like click, change and mouseDown.

Putting them together

Using querySelectorAll and the forEach() loop we can add and remove a class on click.

To remove all active classes we can use another for each loop. We could also use a querySelector with the remove method which I will show next.

let buttons = document.querySelectorAll('.btn');
console.log(buttons);
buttons.forEach(button => {
button.addEventListener('click', function () {
buttons.forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
});
});

Example

Click the button to run script.

We can simplify this a bit

Instead of using a second forEach loop to remove active we can use a conditional (ternary) operator. The ? ternary operator will check if the active class exists. If it does, then with the remove method it will remove it from the DOM.

const navLinks = document.querySelectorAll('.example2 .btn');
navLinks.forEach(navLink => {
navLink.addEventListener('click', () => {
document.querySelector('.example2 .active')?.classList.remove('active');
navLink.classList.add('active');
})
})

Resources