Syntax
parent.addEventListener("event", (e) => { if (e.target.matches(selector)) { } })Examples
Understanding Bubbling
An event fired on a child also triggers listeners on its ancestors.
// <div id="outer"><button id="inner">Click</button></div>
document.querySelector("#outer").addEventListener("click", () => {
console.log("Outer div clicked (via bubbling)");
});
document.querySelector("#inner").addEventListener("click", () => {
console.log("Button clicked directly");
});
// Clicking the button logs both messages, in this order:
// "Button clicked directly"
// "Outer div clicked (via bubbling)"Event Delegation
Using one listener on a parent to handle events from many current and future children.
// A single listener handles clicks on ANY .item, even ones added later
document.querySelector("#itemList").addEventListener("click", (event) => {
if (event.target.matches(".item")) {
console.log("Clicked item:", event.target.textContent);
}
});
// Compare to attaching a separate listener to every .item individually,
// which would need to be redone whenever new items are addedstopPropagation()
Preventing an event from continuing to bubble up to ancestors.
document.querySelector("#inner").addEventListener("click", (event) => {
event.stopPropagation(); // the outer div's listener will NOT fire
console.log("Only this listener runs");
});Best practices
- Use event delegation for lists or grids where items are added/removed dynamically - one listener on the parent handles all current and future children
- Use event.target (the actual element clicked) rather than event.currentTarget (the element the listener is attached to) when delegating
- Reserve stopPropagation() for genuine cases where bubbling would cause a real problem - overusing it can break other legitimate listeners expecting the event to bubble
- Combine delegation with matches() or closest() to reliably identify which specific child element triggered the event
Runtime & versions
Browsers and JavaScript runtimes. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
ECMAScript specification