stopPropagation v stopImmediatePropagation
This post will cover what the JavaScript stopPropagation
and stopImmediatePropagation
methods are in event parameters and the difference between them. We will also cover what event capturing is and how it impacts these methods.
stopPropagation
A recent post covered event bubbling. This is the process of executing an event handler on an element, and then its parent and then its parent’s parent …
The stopPropagation
method is available in an event parameter object. When called in an event handler, it stops the bubbling process.
For example, if we have the following HTML:
<div class="container">
<button class="btn">Click me</button>
</div>
… and we have the following event handlers:
const container = document.querySelector(
".container"
);
container.addEventListener("click", function(e) {
console.log("container click", e);
});
const btn = document.querySelector(".btn");
btn.addEventListener("click", function(e) {
e.stopPropagation();
console.log("btn click", e);
});
… and the user clicks the button …
… the event handler on the div container won’t be invoked.
stopImmediatePropagation
Let’s add a second event handler to the button:
btn.addEventListener("click", function(e) {
e.stopPropagation();
console.log("btn click 1", e);
});
btn.addEventListener("click", function(e) { e.stopImmediatePropagation(); console.log("btn click 2", e);});
When the user clicks the button, this time both button handlers are invoked with the div container’s handler still not reached:
What if we want to prevent the second handler on the button from being invoked? Well, this is what stopImmediatePropagation
does:
btn.addEventListener("click", function(e) {
e.stopImmediatePropagation(); console.log("btn click 1", e);
});
So, stopImmediatePropagation
stops other event handlers on the element from being executed and prevents the event from bubbling up.
Nice!
Event capturing
Event capturing is an event phase that happens before the bubbling phase. In this process, the event goes down the DOM tree from the window to the target element. We can attach event handlers to the capturing phase rather than the bubbling phase using the capture
option:
container.addEventListener(
"click",
function(e) {
console.log("container click", e);
},
{ capture: true });
If a user clicks the button, we see that it is the container div that handles the event first now:
stopPropagation
works in the capturing phase as it does in the bubbling phase - it stops other event handlers later in the phase from being executed.
Let’s add stopPropagation
to the container div handler:
container.addEventListener(
"click",
function(e) {
e.stopPropagation(); console.log("container click", e);
},
{ capture: true }
);
If a user clicks the button, we see that only the container div handler is executed:
So, even if other event handlers are in the bubbling phase, they will not be executed. This is because the capturing phase is before the bubbling phase, and stopPropagation
will prevent handlers later in the process, regardless of which phase it is in.
Wrap up
stopPropagation
allows other event handlers on the same element to be executed, while stopImmediatePropagation
prevents this. stopPropagation
and stopImmediatePropagation
prevents event handlers later in the capturing and bubbling phases from being executed.