Introduction
When building modern web applications using JavaScript, we often need to handle user interactions like clicks, typing, scrolling, and more. Normally, we attach event listeners directly to elements such as buttons or links.
But what happens when you have hundreds or even thousands of elements? Or when elements are added dynamically after the page loads?
This is where Event Delegation in JavaScript becomes extremely useful.
In simple words, event delegation is a technique where instead of adding event listeners to multiple child elements, you attach a single event listener to a parent element and handle events using event bubbling.
What is Event Delegation in JavaScript?
Event delegation is a JavaScript technique where a single event listener is added to a parent element to manage events for its child elements.
Instead of attaching event listeners to each child, we rely on the concept of event bubbling.
What is Event Bubbling?
Event bubbling means when an event happens on a child element, it moves upward to its parent elements.
Example flow:
This allows parent elements to listen to child events.
How Event Delegation Works (Code Example)
Here is a simple example using a list:
const parent = document.getElementById('list');
parent.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('List item clicked:', event.target.textContent);
}
});
HTML:
<ul id="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Only one event listener is used to handle all list items.
Why is Event Delegation Useful?
1. Improves Performance
Instead of adding many event listeners, you use just one.
Example:
// Bad approach (multiple listeners)
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
console.log('Clicked');
});
});
// Good approach (event delegation)
document.getElementById('container').addEventListener('click', (e) => {
if (e.target.tagName === 'BUTTON') {
console.log('Clicked');
}
});
2. Works with Dynamic Elements
const list = document.getElementById('list');
list.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') {
alert('Clicked: ' + event.target.textContent);
}
});
// Dynamically adding new item
const newItem = document.createElement('li');
newItem.textContent = 'New Item';
list.appendChild(newItem);
The new item automatically works without adding a new listener.
3. Cleaner Code
You avoid repeating code for every element.
Real-World Example: Todo App
const todoList = document.getElementById('todoList');
todoList.addEventListener('click', function(event) {
if (event.target.classList.contains('delete-btn')) {
event.target.parentElement.remove();
}
});
HTML:
<ul id="todoList">
<li>
Task 1 <button class="delete-btn">Delete</button>
</li>
</ul>
Works for all current and future tasks.
Important Concepts
event.target
console.log(event.target);
Gives the actual clicked element.
event.currentTarget
console.log(event.currentTarget);
Gives the element where listener is attached.
When to Use Event Delegation
Large number of elements
Dynamic UI updates
Performance optimization
Advantages
Better performance
Less memory usage
Handles dynamic elements
Disadvantages
Summary
Event delegation in JavaScript is a smart way to handle events efficiently using a single event listener. It improves performance, reduces code complexity, and works perfectly with dynamic content, making it an essential concept for modern web development.