Event delegation
Event delegation is a JavaScript technique where we attach the handler not to every element but to their common parent, and use event bubbling to determine which element the action actually happened on. In other words: a single listener manages the events of many child elements.
Theory
TL;DR
- One handler on the parent element instead of a hundred handlers on the children.
- It works thanks to bubbling: the child's event rises to the parent, which is where it is caught.
- The specific element is identified through
event.target, usually withmatches()orclosest(). - It automatically covers elements added to the DOM later.
- It does not work for events that do not bubble (
focus,blur,mouseenter,mouseleave).
Quick example
Say we need to handle clicks on 100 buttons.
The naive way, a listener on every button:
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
console.log('clicked');
});
});The right way, delegation:
document.body.addEventListener('click', (event) => {
if (event.target.matches('button')) {
console.log('clicked');
}
});Why it is worth doing
The key points to name in an interview:
- Fewer handlers, therefore less memory and a faster page.
- It works for dynamically added elements: even if an element appeared later, the parent handler still catches it.
- Better manageability: all the logic lives in one place instead of being smeared across the DOM tree.
- Easier cleanup: to detach the behaviour you remove one listener instead of walking every node.
How it works
- The user clicks a button.
- The event bubbles up through the DOM tree.
- The handler on
body(or on any common ancestor) intercepts the event. - We inspect
event.targetto identify the candidate element.
A more robust check, for when the button contains nested markup (an icon, a <span>):
list.addEventListener('click', (event) => {
const item = event.target.closest('li');
if (!item || !list.contains(item)) return;
console.log('Item clicked:', item.dataset.id);
});closest() walks up from the actual target until it finds a matching element, so a click on an icon inside the item is handled correctly too.
target versus currentTarget
This is the most common interview slip:
event.targetis the element that was clicked, that is, the source of the event.event.currentTargetis the element the listener is attached to, that is, the parent.
| Property | What it points at | In delegation |
|---|---|---|
event.target | The real target of the event | The child element we care about |
event.currentTarget | The element holding the listener | The parent container |
Inside a regular handler function this equals event.currentTarget, not target.
When delegation is not a fit
- The event does not bubble. Use
focusinandfocusoutinstead offocusandblur, andmouseoverandmouseoutinstead ofmouseenterandmouseleave. - Someone on the path called
stopPropagation(). The event then never reaches the parent listener and delegation silently stops working. - Very hot events on a large container. For
mousemoveorscrolla single handler ondocumentcan become the bottleneck; point listeners or throttling are better there.
A short definition, if the interviewer asks for the brief version: event delegation is a technique where one handler on a parent element processes the events of many child elements by relying on event bubbling.
Common mistakes
- Confusing
targetwithcurrentTarget, and then wondering why the check always yields the parent container. - Checking only
event.target.matches(...)where the target can be a nested node. Useclosest(). - Attaching the listener straight to
documentfor no reason. Pick the nearest common ancestor: fewer stray hits and fewer conflicts with other code. - Forgetting to verify that the found element really sits inside the container. Without
container.contains(item)you can match something from an unrelated block. - Counting on delegation for events that do not bubble, and then spending a long time on why the handler never fires.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.