449 Stimmen

stopPropagation vs. stopImmediatePropagation

Was ist der Unterschied zwischen event.stopPropagation() et event.stopImmediatePropagation() ?

12 Stimmen

Ich ermutige den Leser, sich nicht nur an die akzeptierte Antwort zu halten, sondern auch die anderen Antworten zu lesen, insbesondere die von Robert Siemer, die sehr aufschlussreich ist. Um sie zu verstehen, ist eine gute Kenntnis der Funktionsweise der Ausbreitung erforderlich.

403voto

Dave Punkte 6308

stopPropagation verhindert jede Elternteil Handler vor der Ausführung stopImmediatePropagation wird verhindern, dass übergeordnete Handler und auch jede andere Handler von der Ausführung

Kurzes Beispiel aus dem jquery-Dokumentation:

$("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>

Beachten Sie, dass die Reihenfolge der Ereignisbindung hier wichtig ist!

$("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>

12 Stimmen

Sie betonen "Eltern", aber in Wirklichkeit hören beide auch auf, Kinder zu erfassen, wenn sie in der Erfassungsphase aufgerufen werden! Siehe meine Antwort für weitere Einzelheiten.

0 Stimmen

Ist es möglich, andere Handler zu verhindern, aber nicht die übergeordneten Handler?

2 Stimmen

@AndrewFount Ja, wenn Sie die volle Kontrolle über den Code haben: Verschieben Sie die entsprechenden Handler in die Capture-Phase, die vor der Bubble-Phase liegt und es Ihnen ermöglicht, die Aufrufkette zu unterbrechen auf dem Weg nach unten (und nicht auf dem Weg nach oben).

120voto

Robert Siemer Punkte 28819

Überraschenderweise, todos andere Antworten sagen nur die halbe Wahrheit oder sind sogar falsch!

  • e.stopImmediatePropagation() verhindert, dass ein weiterer Handler für dieses Ereignis aufgerufen wird, keine Ausnahmen
  • e.stopPropagation() ist ähnlich, ruft aber trotzdem alle Handler für diese Phase en dieses Element wenn nicht bereits aufgerufen

Welche Phase?

So wird z. B. ein Klick-Ereignis immer zuerst ganz nach unten im DOM wandern (als "Capture-Phase" bezeichnet), schließlich den Ursprung des Ereignisses erreichen ("Target-Phase") und dann wieder nach oben wandern ("Bubble-Phase"). Und mit addEventListener() können Sie mehrere Handler für die Erfassungs- und die Blasenphase unabhängig voneinander registrieren. (Die Zielphase ruft Handler beider Typen auf dem Ziel auf, ohne zu unterscheiden).

Und genau das ist es, was in den anderen Antworten nicht stimmt:

  • Zitat: "event.stopPropagation() ermöglicht die Ausführung anderer Handler für dasselbe Element"
    • Korrektur: Wenn in der Fangphase angehalten wird, werden die Handler der Blasenphase nie erreicht, sie auch auf demselben Element zu überspringen
  • Zitat: "event.stopPropagation() [...] wird nur verwendet, um die Ausführung des entsprechenden übergeordneten Handlers zu stoppen"
    • Korrektur: Wenn die Ausbreitung in der Erfassungsphase gestoppt wird, werden die Handler auf allen Kinder, einschließlich der Zielperson werden auch nicht angerufen, nicht nur Eltern
    • ...und: Wenn die Ausbreitung in der Blasenphase gestoppt wird, wurden alle Handler der Einfangphase bereits aufgerufen, auch die der Eltern.

A <a href="https://jsfiddle.net/siemer/3qfo57zj/17/" rel="noreferrer">fiddle </a>und mozilla.org <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase" rel="noreferrer">Ereignisphase </a>Erklärung mit Demo.

64voto

Anurag Punkte 136648

Ein kleines Beispiel soll zeigen, wie diese beiden Ausbreitungsstopps funktionieren.

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>

Es sind drei Ereignishandler gebunden. Wenn wir keine Weitergabe stoppen, dann sollte es vier Warnungen geben - drei auf dem untergeordneten Div und eine auf dem übergeordneten Div.

Wenn wir das Ereignis von der Ausbreitung zu stoppen, dann wird es 3 Warnungen (alle auf der inneren Kind div). Da das Ereignis nicht propagieren bis die DOM-Hierarchie, die übergeordnete div wird nicht sehen, und seine Handler wird nicht ausgelöst.

Wenn die Ausbreitung sofort gestoppt wird, gibt es nur noch eine Meldung. Obwohl es drei Event-Handler gibt, die an das innere Child-Div angehängt sind, wird nur einer ausgeführt und jede weitere Ausbreitung wird sofort beendet, sogar innerhalb desselben Elements.

0 Stimmen

Beide stopPropagation() Varianten werden auch nicht mehr in der DOM-Hierarchie nach unten weitergegeben. Nicht nur nach oben. Bitte überprüfen Sie meine Antwort für Einzelheiten zur Erfassungsphase.

35voto

nonopolarity Punkte 138211

Ich bin ein Nachzügler, aber vielleicht kann ich das an einem konkreten Beispiel erläutern:

Nehmen wir an, Sie haben eine <table> , mit <tr> und dann <td> . Nehmen wir an, Sie setzen 3 Event-Handler für die <td> Element, wenn Sie dann event.stopPropagation() im ersten Ereignis-Handler, den Sie für <td> , dann alle Ereignisbehandler für <td> wird noch laufen aber das Ereignis überträgt sich nicht auf <tr> ou <table> (und geht nicht auf und ab bis <body> , <html> , document y window ).

Wenn Sie nun aber event.stopImmediatePropagation() in Ihrem ersten Event-Handler, dann, die beiden anderen Ereignisbehandler für <td> wird nicht ausgeführt und wird sich nicht bis zu <tr> , <table> (und geht nicht auf und ab bis <body> , <html> , document y window ).

Beachten Sie, dass es nicht nur für <td> . Für andere Elemente gilt das gleiche Prinzip.

33voto

SLaks Punkte 832502

event.stopPropagation verhindert, dass Handler auf übergeordneten Elementen ausgeführt werden.
Aufruf von event.stopImmediatePropagation verhindert auch die Ausführung anderer Handler für dasselbe Element.

35 Stimmen

Erwähnenswert ist, dass die Ereignis-Handler in der Reihenfolge ausgeführt werden, in der sie an das Element angehängt worden sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X