All topics
DOMbeginner

preventDefault vs stopPropagation

Two distinct event methods often confused: one cancels the browser's default action for an event, the other stops the event from traveling further through the DOM.

Two methods, two unrelated jobs. They are confused constantly.

preventDefault() is like telling airport security 'don't let this specific passenger board the plane' — it stops one particular downstream consequence but doesn't stop word of the incident from spreading through the terminal (propagation). stopPropagation() is the opposite: it's like cutting the radio silence so nobody further down the chain of command even hears about the incident, but the passenger might still board the plane (default action) if nobody told security to stop them.

Key Concepts

1
    e.preventDefault()    cancel the browser's default action
    e.stopPropagation()   stop the event travelling further
2
preventDefault stops what the browser would do.
    form.addEventListener('submit', (e) => {
      e.preventDefault();      // do not navigate
      submitViaFetch();
    });
preventDefault
3
    link.addEventListener('click', (e) => e.preventDefault());  // do not follow
4
The event still bubbles to every ancestor. You have only cancelled the browser's behaviour.
5
stopPropagation stops the journey.
    inner.addEventListener('click', (e) => {
      e.stopPropagation();     // the outer handler never runs
    });
stopPropagation
6
The default action still happens. A link still navigates.
7
So the four combinations are all meaningful.
    neither              handler runs, event bubbles, default happens
    preventDefault       no default, still bubbles
    stopPropagation      default happens, no ancestors
    both                 nothing else at all
8
The classic case for both: a custom control inside a clickable parent:
9
    button.addEventListener('click', (e) => {
      e.preventDefault();      // do not submit the form
      e.stopPropagation();     // do not trigger the row's click
      openMenu();
    });
10
return false is not a synonym. In a plain listener it does nothing. In a jQuery handler it does both — which is where the confusion originates, and why mixed codebases behave inconsistently.
return false
11
Not everything is cancellable.
    e.cancelable     // false for some events
    e.defaultPrevented
12
A passive: true listener cannot cancel at all, and calling preventDefault there logs a warning and does nothing — which is the point of passive, since the browser can then scroll without waiting.
passive: truepreventDefaultpassive
13
Why stopPropagation is worth avoiding by default. It breaks anything relying on delegation higher up: analytics, a dropdown that closes on outside clicks, a framework's own handlers.
stopPropagation
14
The alternative is usually a check in the outer handler instead:
15
    if (e.target.closest('.menu')) return;   // ignore clicks inside
16
What the interviewer is probing.1. "What does each one do?" Probing: the distinction. Stalls: "Both cancel the event." Moves up: preventDefault cancels the browser's default action; stopPropagation stops the event travelling further through the tree. They are independent.
17
2. "A form still submits despite stopPropagation. Why?" Probing: applying the distinction. Stalls: "It should not." Moves up: stopping propagation does not cancel the default action — you need preventDefault.
18
3. "What does returning false do in a handler?" Probing: the legacy behaviour. Stalls: "Nothing." Moves up: in a jQuery handler it does both; in a plain addEventListener handler it does nothing at all.
19
4. "What is stopImmediatePropagation for?" Probing: the third option. Stalls: "Same as stopPropagation." Moves up: it also prevents other handlers on the same element from running.