What is event bubbling and capturing in the DOM?

JavaScript DOM Intermediate 1–2 Yrs2–3 Yrs Conceptual 1 min read

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).