What is event bubbling and capturing in the DOM?
Quick Answer
When an event fires on an element, it propagates in three phases: capture (document → target, listeners with {capture: true}), target (on the element itself), then bubble (target → document, the default). event.stopPropagation() halts further travel; preventDefault() cancels the browser's default action.
An event goes through three phases. Capturing comes first — it travels down from the document to the target element — then it fires on the target, then it bubbles back up. By default your listeners run during bubbling; you opt into capturing with {capture: true}. Bubbling is what makes event delegation work: I put one listener on a container and check event.target to see which child was clicked, which is efficient and handles elements added later. stopPropagation halts the travel and preventDefault cancels the default browser behaviour — they're separate things.
- By default
addEventListener(type, fn)listens in the bubbling phase. Pass{ capture: true }for the capture phase. - Event delegation relies on bubbling: one listener on a parent handles events from any descendant via
event.target— great for dynamic lists. stopPropagation()stops the event travelling;stopImmediatePropagation()also stops other listeners on the same element.- Some events don't bubble (
focus,blur,mouseenter) — use the capturing phase or the bubbling equivalents (focusin,mouseover).