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 further2
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 follow4
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 all8
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.defaultPrevented12
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 inside16
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.