Event Delegation
Event propagation is how events travel through the DOM tree. When an event occurs on an element, it doesn't just affect that element but also travels through its ancestors in the DOM hierarchy. There are two main phases of event propagation:
- Capturing Phase: Events start from the root element and travel down to the target element
- Bubbling Phase: Events start from the target element and bubble up to the root element
The Event Flow
The complete event flow consists of three phases:
- Capturing Phase: From window to the target element
- Target Phase: The event reaches the target element
- Bubbling Phase: From the target element back up to the window
Example: Capturing vs Bubbling
document.querySelector('#grandparent').addEventListener('click', function () {
console.log('Grandparent clicked');
}, true); // true enables capturing phase
document.querySelector('#parent').addEventListener('click', function () {
console.log('Parent clicked');
}, true);
document.querySelector('#child').addEventListener('click', function (e) {
console.log('Child clicked');
e.stopPropagation(); // Stops the event from further propagation
}, false); // false (default) uses bubbling phase
What happens when the child is clicked?
- Capturing phase starts: Grandparent → Parent
- Target phase: Child
- Bubbling phase: Stops immediately due to
e.stopPropagation()
Without stopPropagation()
, the event would continue bubbling up.
Event Delegation
Event delegation is a technique that leverages event bubbling to handle events efficiently, especially when dealing with multiple similar elements.
Example
document.querySelector('#parent').addEventListener('click', function (e) {
if (e.target.id === 'child') {
console.log('Child clicked');
}
});
This pattern is particularly useful for:
- Dynamic elements that might be added/removed from the DOM
- Lists with many items
- Performance optimization when dealing with many elements
Benefits of This Approach
- Efficiency: Only one event listener for multiple elements
- Dynamic elements: Works with elements added after page load
- Memory: Reduces the number of event handlers in memory
- Simplicity: Centralizes event handling logic
This pattern is particularly useful when working with lists, tables, or any UI where you have multiple similar interactive elements.
Practical Tips
- Use capturing rarely, bubbling is more common
stopPropagation()
prevents further propagation in either directionstopImmediatePropagation()
prevents other handlers on the same element from executing- Event delegation can significantly improve performance for complex UIs
Further Reading
- Event Deligation:
- JavaScript Event Listeners: