Learn what, why, and how to use the Event Delegation method in JavaScript.
What is JavaScript Event Delegation and when should you use it?
In short, event delegation is a JavaScript method that allows you to interact with child elements by only using a single event listener, on the parent element. With event delegation, you can avoid having to add event handlers to every child element, but you can still find and manipulate them.
You’ll see why this is powerful in a moment.
Say you have a list of items inside a list. When the user clicks on either list item, you want something to happen.
Let’s check out two different ways of doing that.
Attach event listeners to each element
A common way of gaining access to individual element items on a list is to loop through them e.g. with the for
loop. And then attach event listeners to each element:
let allExerciseItems = document.querySelectorAll(".exercise-item")
for (let exerciseItem of allExerciseItems) {
exerciseItem.addEventListener("click", function(event) {
// Do something with target child element
event.target.classList.toggle("exercise-complete")
});
}
Example
https://codepen.io/StrengthandFreedom/pen/KBZezV/
Access items with Event Delegation
Event delegation is totally different from the for loop example you saw above. Instead of iterating (looping) through each element we want access to, we simply target the parent element, like this:
// Get parent element, add a click event listener
document.querySelector(".exercise-list").addEventListener("click", function(event) {
if(event.target.classList.contains('exercise-item')) {
// Do something with target child element
event.target.classList.toggle('exercise-complete')
}
})
CodePen example.
Note: instead of classList.contains
you can use the element.matches API matches()
if you need more selector flexibility.
As you can see, the result is the exact same. When you click on either exercise element item on the this, they toggle the exercise-complete
class. What’s different is the method we used to achieve this result.
So why should you use the event delegation method instead of the event handling + for loop method?
Let’s discuss that next!
Event Delegation and Performance
Imagine that you’re dealing with a web application where you have hundreds or thousands of dynamically created elements per day, hour, or even minute. An example could be a Booking calender for hotel reservation. Or a social media platform like Twitter which requires frequent live updates to deliver an optimal user experience.
If every element in your web UI has event listeners attached to them, this type of scenario can quickly become hardware intensive.
All those event listeners can hog up your users CPU. They can cause an enormous amount of function references sitting in memory. This can cause memory leaks and general performance degradation.
I don’t know much about GC (Garbage Collection). I’ve had the luxury of more or less solely writing JavaScript (a high-level programming language). But one thing that I do know, is that GC in the browser can be unpredictable due to the numerous different vendor browsers (Chrome, FireFox etc). And, of course, the countless of devices (smartphones, laptops etc.).
Having event listeners attached to everything, like you saw in the loop example, will increase the amount of garbage collection your web app needs. This will almost invariably decrease performance.
It’s generally more performant when you have a single event listener on a parent element that listens for all clicks on its child elements than to attach event listeners to every single child element.