stopPropagation vs. stopImmediatePropagation

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>

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.


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.