Capture phase
The event travels from outer ancestors toward the target.
Many events travel through the DOM. Capturing runs on the way down; bubbling runs on the way back up.
parent.addEventListener("click", handleParent);
child.addEventListener("click", handleChild);
// Child click can be observed by parent.
Events & Forms
When an event happens on an element, the browser creates a propagation path through ancestors. The capture phase travels down, then the target phase runs, then bubbling travels up.
Most event listeners run during bubbling by default. That is why a click inside a list item can be handled by a listener on the list.
stopPropagation interrupts propagation. It should be used sparingly because it can block other code that legitimately needs to observe the event.
The event travels from outer ancestors toward the target.
The event reaches the original target.
The event travels back up through ancestors.
Stops the event from continuing through the path.
Examples
list.addEventListener("click", event => {
const item = event.target.closest("li");
if (!item) return;
item.classList.toggle("active");
});
document.addEventListener("click", event => {
event.stopPropagation();
});
Code patterns
These examples are the event patterns you will reuse constantly: listen, inspect, prevent, delegate, validate and submit.
Parent sees child clicks.
list.addEventListener("click", event => {
console.log("list received click");
});
Listen during the capture phase.
panel.addEventListener("click", handleClick, { capture: true });
Use only when the event must not continue.
button.addEventListener("click", event => {
event.stopPropagation();
});
eventPhase shows where the event is.
console.log(event.eventPhase);
Rules that matter
Events are user-facing code. Good handlers stay small, respect native behavior and keep visual, semantic and data state aligned.
Events move through ancestors before and after the target.
Most addEventListener calls observe the bubble phase.
It changes when the listener runs.
It can break menus, analytics and delegated handlers.
Delegated handlers often need the relevant ancestor.
focus and blur have bubbling alternatives such as focusin and focusout.
Production thinking
Propagation is the reason event delegation works and the reason some clicks seem to trigger multiple handlers.
Propagation should not interfere with keyboard activation or focus behavior.
Production code should use propagation intentionally instead of fighting it with stopPropagation everywhere.
Propagation mostly affects interaction, but broken click handling can block navigation to crawlable pages.
Live code lab
The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.
Mini assignment
Practice assignment
Try it yourself
Self-check
If you can explain what fires, where it fires and what default behavior remains, you understand the interaction.
Senior audit upgrade
Events travel through the document before and after they reach the target.
capture phase: window -> document -> parent -> target target phase: target handler bubble phase: target -> parent -> document -> window