Reputation: 25408
This image is taken from DOM ENLIGHTENMENT book. It says stopPropagation() will stop the capture and bubble event flow phases.
I know stopPropagation() will stop propagation and won't execute the callback function in the bubbling phase.
But in the following code snippet after using the stopPropagation() on the button, the body event callback method is still executed.
Does stopPropagation() also stop the event flow phase in the capture phase also?
const button = document.querySelector('button');
document.body.addEventListener('click', e => {
console.log('Body event triggered');
}, true);
button.addEventListener('click', e => {
console.log('button is clicked 1');
});
button.addEventListener('click', e => {
e.stopPropagation();
console.log('button is clicked 2');
});
button.addEventListener('click', e => {
console.log('button is clicked 3');
});
<button> click me </button>
Upvotes: 0
Views: 222
Reputation: 1074595
But in the following code snippet after using the stopPropagation() on the button, the body event callback method is still executed.
All your button
click
handlers are target/bubbling handlers, not capture handlers. At the point you're calling stopPropagation
, the capture phase is already done. If you had a target/bubbling handler on document.body
, you'd see that it wasn't called.
Note that propagation relates to moving from one element to its parent (bubbling) or descendant (capture) but doesn't affect processing other handlers on the same element, which is why your handler calling stopPropgation
didn't stop the other handlers on button
both firing. (If you'd used stopImmediatePropagation
, you would have stopped the third handler because it stops things right away, even in the middle of the current element's handlers.)
Here's an example cancelling propagation during the capture phase:
const div = document.getElementById("middle");
const button = document.getElementById("button");
// Capture phase on body
document.body.addEventListener("click", e => {
console.log("body capture handler");
}, true);
// Target/bubbling phase on body
document.body.addEventListener("click", e => {
console.log("body target/bubbling handler");
});
// Capture phase on middle
middle.addEventListener("click", e => {
console.log("middle capture handler - stopping propagation");
e.stopPropagation();
}, true);
// Target/bubbling phase on middle
middle.addEventListener("click", e => {
console.log("middle target/bubbling handler");
});
// Capture phase on button
button.addEventListener("click", e => {
console.log("button capture handler");
}, true);
// Target/bubbling phase on button
button.addEventListener("click", e => {
console.log("button target/bubbling handler");
});
<div id="middle">
<input type="button" id="button" value="Click me">
</div>
Notice that:
The capture phase handler on button
didn't fire, because propagation was stopped before it got there; and
None of the target/bubbling phase handlers fired, since propagation was stopped before the target phase (and thus before the bubbling phase).
I find this diagram from the DOM3 Events spec really useful for picturing this stuff:
Upvotes: 2