šŸŽ Checkout my Learn React by Making a Game course and get 1 month Free on Skillshare!

Using addEventListener on multiple elements in Javascript

How can we use the addEventListener() on multiple elements in vanilla javascript:

How addEventLister works

Let's take a basic example of addEventListener() :

const doOnClick = (e) => {
    // code here
}
myButton.addEventListener('click', doOnClick)

What addEventListener() does is to execute a function when an event takes place on a specific element. And remember that it is better to use a named function as your event listener.

Use addEventListener for multiple elements with the same class

By default, addEventListener() is made to work with just one element, as seen in the above example.

If we want to add it to all the elements that have a specific class we can just iterate through the array of elements and add it manually:

const doOnClick = (e) => {
    // code here
}

document.querySelectorAll('.foo').forEach((el) => {
  el.addEventListener('click', doOnClick)
})

However, keep in mind that using event bubbling may be a better option for performance.

Add event listeners for multiple ids or classes

In the previous example, we were looking for just one selector (the .foo class).

But, what if we want to add the same event listener to different ids and/or different classes?

Well, for this case we can do something like:

const doOnClick = (e) => alert("ok")

let elements = [
  ...document.querySelectorAll('.foo'),
  ...document.querySelectorAll('.bar'),
  ...document.querySelectorAll('#red'),
  ...document.querySelectorAll('#blue'),
]

elements.forEach(
  e => e.addEventListener('click', doOnClick)
)

We first query for the elements, and using the spread operator we construct an array with all the received elements.

This code will target any element with class foo or bar and any element with an id of red or blue. See the full codepen here.

Performance tip: use addEventLister with event bubbling

Events bubble up, meaning that once an event takes place on an element, that event is received also by the parents of that element.

Let's say we have the following:

<div class="container">
    <div class="red">The red div</div>
    <div class="blue">The blue div</div>
</div>

If we click on the any of .red or .blue elements also the .container element will receive the click event.

With this in mind if we want to listen to a specific event on multiple elements at once we can attach a listener to a parent element that the elements are contained within. For example, we can use the window or the document:

const doOnClick = (event) => {
    if (event.target.matches('.red') || event.target.matches('.blue')) {
        // Do something...
    }
}

document.addEventListener('click', doOnClick);

Using the event target we can check if the element that triggered the event meets our condition (has a class, or a specific id).

Even if this approach is a bit less intuitive it provides an important performance boost because each individual event listener that we add will consume memory.

Using addEventListner with event bubbling for events that don't bubble

As a final thought please note that there are events that don't automatically bubble forward to the parent. Events such as focus or blur.

To make this work you will need to force the bubbling, by setting the optional useCapture parameter to true:

document.addEventListener('focus', doOnClick, true);

To find out if an event bubbles or not you can check out the mozilla docs

Happy event listening!

šŸ“– 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.

šŸ“– 50 Javascript, React and NextJs Projects

Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.


Leave a Reply

Your email address will not be published. Required fields are marked *