stopPropagation vs. stopImmediatePropagation

stopPropagation vs. stopImmediatePropagation

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

Solutions/Answers:

Solution 1:

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>

Solution 2:

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.

Related:  Why put JavaScript in head

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.

Solution 3:

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.

Related:  $on and $broadcast in angular

Solution 4:

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

Solution 5:

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.

Related:  How to include external js file in Angular 4 and call function from angular to js

Solution 6:

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