Event Delegation in JavaScript
Sometimes we don’t want to attach event listeners to every single elements.
Instead, we can attach just one listener to a parent - and use it to handle all events from its children.
This techniwue is called event delegation
Why use delegation?
We can use event delegation when:
We have lots of similar elements (like list items or buttons)
We want to reduce the number of listeners in memory
We added elements to the page dynamically
We want cleaner, smarter code.
Basic example: clicking on list items
Let’s say we have a list like this:
<ul id="userList">
<li>Eva</li>
<li>Mia</li>
<li>Anna</li>
</ul>
Instead of adding a click listener to every <li>
, we can add one to the parent <ul>
const userList = document.getElementById('userList');
userList.addEventListener('click', (event) => {
if(event.target.tagName === 'LI') {
console.log('Clicked on:', event.target.textContent);
}
});
Now any <li>
inside #userList
will be handled, even if we add new ones latter.
Dynamic content? Still works.
Delegation works beautifully with dynamically created elements:
const newItem = document.createElement('li');
newItem.textContent = 'Elle';
userList.append(newItem);
//No new listener needed!
We don’t need to reattach listeners - the parent already listens.
How it work (under the hood)
Events bubble up from the clicked element
The parent (listener) catches the event
We use event.target to check which element triggered it
If it matches what we’re looking for (like a
<li>
) we run logic
Notes
We can use delegation for click
, change
, input
and more
Use event.target to find what was clicked
Combine with .matches()
for more precise control
Greate for performance, cleaner code and dynamic interfaces