[javascript] stopPropagation vs. stopImmediatePropagation

What's the difference between event.stopPropagation() and event.stopImmediatePropagation()?

This question is related to javascript jquery

The answer is


Here I am adding my JSfiddle example for stopPropagation vs stopImmediatePropagation. JSFIDDLE

_x000D_
_x000D_
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_
_x000D_
_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:

_x000D_
_x000D_
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_
_x000D_
_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.

_x000D_
_x000D_
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">&nbsp;</div>_x000D_
</div>_x000D_
_x000D_
<button id="stopPropagation">Stop Propogation</button>_x000D_
<button id="stopImmediatePropagation" ">Stop Immediate Propogation</button>
_x000D_
_x000D_
_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 exceptions
  • e.stopPropagation() is similar, but does still call all handlers for this phase on this element if not called already

What 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:

  • quote: “event.stopPropagation() allows other handlers on the same element to be executed”
    • correction: if stopped in the capture phase, bubble phase handlers will never be reached, also skipping them on the same element
  • quote: “event.stopPropagation() [...] is used to stop executions of its corresponding parent handler only”
    • correction: if propagation is stopped in the capture phase, handlers on any children, including the target aren’t called either, not only parents
    • ...and: if propagation is stopped in the bubble phase, all capture phase handlers have already been called, including those on parents

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.