What's the difference between event.stopPropagation()
and event.stopImmediatePropagation()
?
This question is related to
javascript
jquery
Here I am adding my JSfiddle example for stopPropagation vs stopImmediatePropagation. JSFIDDLE
let stopProp = document.getElementById('stopPropagation');_x000D_
let stopImmediate = document.getElementById('stopImmediatebtn');_x000D_
let defaultbtn = document.getElementById("defalut-btn");_x000D_
_x000D_
_x000D_
stopProp.addEventListener("click", function(event){_x000D_
event.stopPropagation();_x000D_
console.log('stopPropagation..')_x000D_
_x000D_
})_x000D_
stopProp.addEventListener("click", function(event){_x000D_
console.log('AnotherClick')_x000D_
_x000D_
})_x000D_
stopImmediate.addEventListener("click", function(event){_x000D_
event.stopImmediatePropagation();_x000D_
console.log('stopimmediate')_x000D_
})_x000D_
_x000D_
stopImmediate.addEventListener("click", function(event){_x000D_
console.log('ImmediateStop Another event wont work')_x000D_
})_x000D_
_x000D_
defaultbtn.addEventListener("click", function(event){_x000D_
alert("Default Clik");_x000D_
})_x000D_
defaultbtn.addEventListener("click", function(event){_x000D_
console.log("Second event defined will also work same time...")_x000D_
})
_x000D_
div{_x000D_
margin: 10px;_x000D_
}
_x000D_
<p>_x000D_
The simple example for event.stopPropagation and stopImmediatePropagation?_x000D_
Please open console to view the results and click both button._x000D_
</p>_x000D_
<div >_x000D_
<button id="stopPropagation">_x000D_
stopPropagation-Button_x000D_
</button>_x000D_
</div>_x000D_
<div id="grand-div">_x000D_
<div class="new" id="parent-div">_x000D_
<button id="stopImmediatebtn">_x000D_
StopImmediate_x000D_
</button>_x000D_
</div>_x000D_
</div>_x000D_
<div>_x000D_
<button id="defalut-btn">_x000D_
Normat Button_x000D_
</button>_x000D_
</div>
_x000D_
1)event.stopPropagation():
=>It is used to stop executions of its corresponding parent handler only.
2) event.stopImmediatePropagation():
=> It is used to stop the execution of its corresponding parent handler and also handler or function attached to itself except the current handler.
=> It also stops all the handler attached to the current element of entire DOM.
Here is the example: Jsfiddle!
Thanks, -Sahil
Here is a demo to illustrate the difference:
document.querySelectorAll("button")[0].addEventListener('click', e=>{
e.stopPropagation();
alert(1);
});
document.querySelectorAll("button")[1].addEventListener('click', e=>{
e.stopImmediatePropagation();
alert(1);
});
document.querySelectorAll("button")[0].addEventListener('click', e=>{
alert(2);
});
document.querySelectorAll("button")[1].addEventListener('click', e=>{
alert(2);
});
_x000D_
<div onclick="alert(3)">
<button>1...2</button>
<button>1</button>
</div>
_x000D_
Notice that you can attach multiple event handlers to an event on an element.
event.stopPropagation
will prevent handlers on parent elements from running.
Calling event.stopImmediatePropagation
will also prevent other handlers on the same element from running.
A small example to demonstrate how both these propagation stoppages work.
var state = {_x000D_
stopPropagation: false,_x000D_
stopImmediatePropagation: false_x000D_
};_x000D_
_x000D_
function handlePropagation(event) {_x000D_
if (state.stopPropagation) {_x000D_
event.stopPropagation();_x000D_
}_x000D_
_x000D_
if (state.stopImmediatePropagation) {_x000D_
event.stopImmediatePropagation();_x000D_
}_x000D_
}_x000D_
_x000D_
$("#child").click(function(e) {_x000D_
handlePropagation(e);_x000D_
console.log("First event handler on #child");_x000D_
});_x000D_
_x000D_
_x000D_
$("#child").click(function(e) {_x000D_
handlePropagation(e);_x000D_
console.log("Second event handler on #child");_x000D_
});_x000D_
_x000D_
// First this event will fire on the child element, then propogate up and_x000D_
// fire for the parent element._x000D_
$("div").click(function(e) {_x000D_
handlePropagation(e);_x000D_
console.log("Event handler on div: #" + this.id);_x000D_
});_x000D_
_x000D_
_x000D_
// Enable/disable propogation_x000D_
$("button").click(function() {_x000D_
var objectId = this.id;_x000D_
$(this).toggleClass('active');_x000D_
state[objectId] = $(this).hasClass('active');_x000D_
console.log('---------------------');_x000D_
});
_x000D_
div {_x000D_
padding: 1em;_x000D_
}_x000D_
_x000D_
#parent {_x000D_
background-color: #CCC;_x000D_
}_x000D_
_x000D_
#child {_x000D_
background-color: #000;_x000D_
padding: 5em;_x000D_
}_x000D_
_x000D_
button {_x000D_
padding: 1em;_x000D_
font-size: 1em;_x000D_
}_x000D_
_x000D_
.active {_x000D_
background-color: green;_x000D_
color: white;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div id="parent">_x000D_
<div id="child"> </div>_x000D_
</div>_x000D_
_x000D_
<button id="stopPropagation">Stop Propogation</button>_x000D_
<button id="stopImmediatePropagation" ">Stop Immediate Propogation</button>
_x000D_
There are three event handlers bound. If we don’t stop any propagation, then there should be four alerts - three on the child div, and one on the parent div.
If we stop the event from propagating, then there will be 3 alerts (all on the inner child div). Since the event won’t propagate up the DOM hierarchy, the parent div won’t see it, and its handler won’t fire.
If we stop propagation immediately, then there will only be 1 alert. Even though there are three event handlers attached to the inner child div, only 1 is executed and any further propagation is killed immediately, even within the same element.
Surprisingly, all other answers only say half the truth or are actually wrong!
e.stopImmediatePropagation()
stops any further handler from being called for this event, no exceptionse.stopPropagation()
is similar, but does still call all handlers for this phase on this element if not called alreadyWhat phase?
E.g. a click event will always first go all the way down the DOM (called “capture phase”), finally reach the origin of the event (“target phase”) and then bubble up again (“bubble phase”). And with addEventListener()
you can register multiple handlers for both capture and bubble phase independently. (Target phase calls handlers of both types on the target without distinguishing.)
And this is what the other answers are incorrect about:
A fiddle and mozilla.org event phase explanation with demo.
I am a late comer, but maybe I can say this with a specific example:
Say, if you have a <table>
, with <tr>
, and then <td>
. Now, let's say you set 3 event handlers for the <td>
element, then if you do event.stopPropagation()
in the first event handler you set for <td>
, then all event handlers for <td>
will still run, but the event just won't propagate to <tr>
or <table>
(and won't go up and up to <body>
, <html>
, document
, and window
).
Now, however, if you use event.stopImmediatePropagation()
in your first event handler, then, the other two event handlers for <td>
WILL NOT run, and won't propagate up to <tr>
, <table>
(and won't go up and up to <body>
, <html>
, document
, and window
).
Note that it is not just for <td>
. For other elements, it will follow the same principle.
From the jQuery API:
In addition to keeping any additional handlers on an element from being executed, this method also stops the bubbling by implicitly calling event.stopPropagation(). To simply prevent the event from bubbling to ancestor elements but allow other event handlers to execute on the same element, we can use event.stopPropagation() instead.
Use event.isImmediatePropagationStopped() to know whether this method was ever called (on that event object).
In short: event.stopPropagation()
allows other handlers on the same element to be executed, while event.stopImmediatePropagation()
prevents every event from running.
event.stopPropagation() allows other handlers on the same element to be executed, while event.stopImmediatePropagation() prevents every event from running. For example, see below jQuery code block.
$("p").click(function(event)
{ event.stopImmediatePropagation();
});
$("p").click(function(event)
{ // This function won't be executed
$(this).css("color", "#fff7e3");
});
If event.stopPropagation was used in previous example, then the next click event on p element which changes the css will fire, but in case event.stopImmediatePropagation(), the next p click event will not fire.
Source: Stackoverflow.com