Concept · The browser
Event bubbling and delegation
Events travel up the tree, so one listener on a parent can handle every child — even ones added later.
When you click a button inside a list item inside a list, the click doesn't stay on the button. A DOM event travels in three phases:
capture: window → document → … → ul → li (listeners with { capture: true })
target: button
bubble: li → ul → … → document → window (normal listeners)Most events bubble, so a listener on any ancestor hears clicks on its descendants. event.target is the element that was actually clicked. event.currentTarget is the element whose listener is running.
Delegation
Instead of attaching a listener to each item, attach one to the container and work out which item was clicked:
list.addEventListener('click', (event) => {
const button = event.target.closest('button[data-action="delete"]')
if (!button || !list.contains(button)) return
removeItem(button.closest('li').dataset.id)
})- One listener instead of thousands, so there's less memory and setup.
- Works for elements added later. New rows need no wiring, which matters when you render lists from data.
closest()handles clicks on an icon inside the button, whereevent.targetis the<svg>or<span>.
React uses this approach internally. It attaches its listeners at the root and dispatches to your components.
Controlling propagation
event.stopPropagation()stops the event from reaching ancestors. Use it rarely, because it silently breaks delegated listeners, analytics and "click outside to close" handlers further up.event.preventDefault()cancels the browser's default action, such as following a link or submitting a form. It doesn't stop bubbling, and the two are often confused.- Some events don't bubble, such as
focus,blur,mouseenterandmouseleave. Use their bubbling versions,focusin,focusout,mouseoverandmouseout, for delegation.
Accessibility
Delegate to real controls. A click listener on a <div> works for mouse users, but keyboard and screen-reader users can't reach it. A <button> gets focus, Enter and Space handling, and a role for free. See the accessibility tree.