459

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

1
  • 15
    I encourage the reader not just to stick to the accepted answer, but also to read the others, especially that of Robert Siemer which is very enlightening. A good knowledge of how propagation works is needed to well understand it. May 26, 2021 at 11:04

10 Answers 10

409

stopPropagation will prevent any parent handlers from being executed stopImmediatePropagation will prevent any parent handlers and also any other handlers from executing

Quick example from the jquery documentation:

$("p").click(function(event) {
  event.stopImmediatePropagation();
});

$("p").click(function(event) {
  // This function won't be executed
  $(this).css("background-color", "#f00");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>example</p>

Note that the order of the event binding is important here!

$("p").click(function(event) {
  // This function will now trigger
  $(this).css("background-color", "#f00");
});

$("p").click(function(event) {
  event.stopImmediatePropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>example</p>

3
  • 12
    You emphasize “parent”, but in reality both also stops entering children as well if called in the capture phase! See my answer for details. Mar 26, 2020 at 7:07
  • Is it possible to prevent other handlers but not parent handlers?
    – Paul R
    May 22, 2021 at 19:26
  • 2
    @AndrewFount Yes, if you have full control over the code: move the relevant handlers to the capture phase, which comes before the bubble phase and allows you to interrupt the call chain on the way down (and not on the way up). Sep 23, 2021 at 10:47
139

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.

7
  • hi @Robert Siemer + 1 excellent answer - Target phase calls handlers of both types on the target without distinguishing - That means that the target phase is executed 2 times, once for the capture phase and once for the bubbling phase, right? (assuming I don't use stopPropagation or stopImmediatePropagation).
    – user19481364
    Feb 16, 2023 at 14:42
  • 2
    @Coder23 No, not right.—The list of handlers of the target element will only be visited once. And all handlers will be called, ignoring the boolean which otherwise decides if it will be called on the way down or up. I.e. an earlier registered handler will be called earlier, even if that boolean is False indicating “bubble phase”. While a later registered handler showing True (“capture phase”) will be called after that. Feb 18, 2023 at 5:50
  • hi @Robert Siemer +1, by way of summary, they work the same in the sense of at what stage the propagation stops, correct? The difference is that stopImmediatePropagation() stops the "pending" handlers of the same event of the element in question, while stopPropagation() does not, only the further handlers of other elements, ALL THIS CONSIDERING THE PHASE, right?
    – user19551894
    Feb 23, 2023 at 14:09
  • 1
    @GeorgeMeijer I think “yes”, but am not sure whether I understood you correctly. Both stop event handling, but not necessarily on “phase borders”. The phases don’t overlap. By the number of elements visited, the capture phase is (usually) a long phase with many elements to visit. The target phase is only for one element. Then the bubble phase (usually) revisits all elements visited in the capture phase but in reverse order.—So a handler on an element in the “middle” off the capture phase can “stop” 2.5 phases, so to say: Half the capture phase will be skipped, so will target and bubble phase. Feb 23, 2023 at 19:29
  • 1
    @GeorgeMeijer ...and that is the same with both stop...Propagation(). (The “non-immediate” version only allows the rest of the handlers on this element to run normal, before cutting short.) Feb 23, 2023 at 19:30
64

A small example to demonstrate how both these propagation stoppages work.

var state = {
  stopPropagation: false,
  stopImmediatePropagation: false
};

function handlePropagation(event) {
  if (state.stopPropagation) {
    event.stopPropagation();
  }

  if (state.stopImmediatePropagation) {
    event.stopImmediatePropagation();
  }
}

$("#child").click(function(e) {
  handlePropagation(e);
  console.log("First event handler on #child");
});


$("#child").click(function(e) {
  handlePropagation(e);
  console.log("Second event handler on #child");
});

// First this event will fire on the child element, then propogate up and
// fire for the parent element.
$("div").click(function(e) {
  handlePropagation(e);
  console.log("Event handler on div: #" + this.id);
});


// Enable/disable propogation
$("button").click(function() {
  var objectId = this.id;
  $(this).toggleClass('active');
  state[objectId] = $(this).hasClass('active');
  console.log('---------------------');
});
div {
  padding: 1em;
}

#parent {
  background-color: #CCC;
}

#child {
  background-color: #000;
  padding: 5em;
}

button {
  padding: 1em;
  font-size: 1em;
}

.active {
  background-color: green;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
  <div id="child">&nbsp;</div>
</div>

<button id="stopPropagation">Stop Propogation</button>
<button id="stopImmediatePropagation" ">Stop Immediate Propogation</button>

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.

1
  • Both stopPropagation() variants will also stop propagating down the DOM hierarchy. Not just up. Please check my answer for details with the capture phase. Mar 26, 2020 at 7:10
38

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.

0
34

event.stopPropagation will prevent handlers on parent elements from running.
Calling event.stopImmediatePropagation will also prevent other handlers on the same element from running.

1
  • 35
    Worth mentioning is that event handlers are executed in the order in which they have been attached to the element. Mar 14, 2011 at 14:15
30

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.

3
  • Just to be sure, the native javascript version of event.stopImmediatePropagation doesn't stop bubbling right? Oct 11, 2016 at 21:12
  • It does, bubbling is when the event is propagated to the parent elements, stopImmediatePropagation stops the event from being propagated period, both of them should prevent bubbling, it's worth nothing that you can also change the mode to capture which will trigger the outermost elements first and only then go down to the children (bubbling is the default, and works in the opposite direction)
    – JonnySerra
    Nov 9, 2017 at 20:56
  • 1
    Not exact, to say the least. Stopping in the capture phase will not allow bubble handlers on the same element to be executed as explained in my answer. Mar 26, 2020 at 7:14
13

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);
});
<div onclick="alert(3)">
   <button>1...2</button>
   <button>1</button>
</div>

Notice that you can attach multiple event handlers to an event on an element.

2
  • 1
    So the difference here is that since the div is the parent of the button that got clicked, stopPropagation() makes sure that 3 is never alerted, whereas stopImmediatePropagation() makes sure that not even other event listeners registered on the button itself, i.e. 2, are executed.
    – Andrew
    Oct 2, 2020 at 17:43
  • I think its best representation of difference, gj
    – Szymon
    Jun 10, 2021 at 14:01
12

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

0
2

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.

2

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

let stopProp = document.getElementById('stopPropagation');
let stopImmediate = document.getElementById('stopImmediatebtn');
let defaultbtn = document.getElementById("defalut-btn");


stopProp.addEventListener("click", function(event){
	event.stopPropagation();
  console.log('stopPropagation..')
  
})
stopProp.addEventListener("click", function(event){
  console.log('AnotherClick')
  
})
stopImmediate.addEventListener("click", function(event){
		event.stopImmediatePropagation();
    console.log('stopimmediate')
})

stopImmediate.addEventListener("click", function(event){
    console.log('ImmediateStop Another event wont work')
})

defaultbtn.addEventListener("click", function(event){
    alert("Default Clik");
})
defaultbtn.addEventListener("click", function(event){
    console.log("Second event defined will also work same time...")
})
div{
  margin: 10px;
}
<p>
The simple example for event.stopPropagation and stopImmediatePropagation?
Please open console to view the results and click both button.
</p>
<div >
<button id="stopPropagation">
stopPropagation-Button
</button>
</div>
<div  id="grand-div">
  <div class="new" id="parent-div">
    <button id="stopImmediatebtn">
    StopImmediate
    </button>
  </div>
</div>
<div>
<button id="defalut-btn">
Normat Button
</button>
</div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.