Skip to content
Optimal Lab

Frontend · interactive

Event propagation

A click on a button doesn't just happen on the button. The event travels down from the window to it (capture), fires on it (target), then travels back up (bubble). Every ancestor gets a chance to react.

<div id=page> · capture

<section class=card>

<button>

Buy

↓ going down · depth 0

  1. 1. page (capture)

page: capture phase.

Listeners

1 of 5

Step 1 of 4

  1. 1

    Capture: window down to the target

    Listeners added with { capture: true } run on the way down. Rarely needed, but useful to intercept first.

    addEventListener("click", fn, true)

  2. 2

    Target

    Listeners on the clicked element itself run.

    event.target is always the button.

  3. 3

    Bubble: back up to the window

    Normal listeners run on each ancestor. stopPropagation() ends the trip; preventDefault() is different, it cancels the browser's default action.

    event.currentTarget is the element whose listener is running.

  4. 4

    Event delegation

    Put one listener on a container instead of hundreds on its children. It also works for elements added later.

    e.target.closest("button")

In production

Tools and technologies

Every DOM event follows this path.

Not tied to one language — use these names when you search docs or design a system.