By Rahul — Google Frontend Engineer
What is Event Delegation?
Instead of attaching an event listener to every child element, you attach ONE listener to the parent and use event.target to figure out which child was clicked. This works because of event bubbling — events travel up from the target element through its ancestors.
The Problem It Solves
Imagine a todo list with 1000 items. Without delegation:
With delegation:
How Event Bubbling Works
When you click a button inside a div inside body, the click event fires on:
- Capture phase: document → html → body → div (top down)
- Target phase: button (the element you clicked)
- Bubble phase: div → body → html → document (bottom up)
Event delegation uses the bubble phase. The listener on the parent catches events that bubble up from children.
Real-World Examples
Data Tables with Actions
React Already Uses Delegation
React attaches a single event listener at the root of your app (since React 17, it is the root container, not document). When you write onClick on a component, React handles delegation internally. This is why e.nativeEvent and e.target sometimes behave differently than you expect.
The closest() Pattern
The most important trick: always use e.target.closest(selector) instead of checking e.target directly. Why? If your button has an icon inside it, e.target will be the icon, not the button.
Production Issues
- stopPropagation() breaking delegation: If any child calls
e.stopPropagation(), the event never reaches the parent. I have seen third-party modals do this and break our delegation setup - Focus/blur do not bubble: Use
focusinandfocusoutinstead - scroll does not bubble: You cannot delegate scroll events
Best Practices
- Always check if the target is inside the delegate container with
container.contains() - Use
data-attributes for action identification instead of class names - Keep the delegation handler focused — do not put 50 conditions in one handler
Summary
Event delegation is a fundamental pattern. It reduces memory usage, handles dynamic content automatically, and is the pattern React uses under the hood. Master closest() and you will write cleaner event handling code.