Ich habe den Artikel unter https://developer.mozilla.org/en/DOM/element.addEventListener gelesen, kann aber das useCapture
Attribut nicht verstehen . Definition gibt es:
Wenn true, gibt useCapture an, dass der Benutzer die Erfassung starten möchte. Nach dem Starten der Erfassung werden alle Ereignisse des angegebenen Typs an den registrierten Listener gesendet, bevor sie an EventTargets darunter in der DOM-Struktur gesendet werden. Ereignisse, die durch den Baum nach oben sprudeln, lösen keinen Listener aus, der für die Verwendung der Erfassung vorgesehen ist.
In diesem Code wird das übergeordnete Ereignis vor dem untergeordneten Ereignis ausgelöst, sodass ich sein Verhalten nicht verstehen kann. Das Dokumentobjekt hat usecapture true und child div hat usecapture auf false gesetzt und document usecapture wird befolgt. Deshalb wird die document-Eigenschaft gegenüber child bevorzugt.
function load() {
document.addEventListener("click", function() {
alert("parent event");
}, true);
document.getElementById("div1").addEventListener("click", function() {
alert("child event");
}, false);
}
<body onload="load()">
<div id="div1">click me</div>
</body>
quelle
no specification is made as to the order in which they will receive the event with regards to the other EventListeners on the EventTarget
. Ich habe nicht alle Browser getestet, daher können sie alle auf die gleiche Weise implementiert werden. Erfassungsereignisse werden jedoch vor nicht erfassten Ereignissen durchgeführt.Ich finde dieses Diagramm sehr nützlich, um die Erfassungs- / Ziel- / Blasenphasen zu verstehen: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
Unten wird der Inhalt aus dem Link extrahiert.
Phasen
Das Ereignis wird über einen Pfad von der Wurzel des Baums zu diesem Zielknoten ausgelöst. Es kann dann lokal auf der Ebene des Zielknotens oder von den Vorfahren eines Ziels weiter oben im Baum verarbeitet werden. Die Ereignisverteilung (auch Ereignisausbreitung genannt) erfolgt in drei Phasen und in der folgenden Reihenfolge:
Die Vorfahren des Ziels werden vor dem ersten Versand des Ereignisses ermittelt. Wenn der Zielknoten während des Versands entfernt wird oder der Vorfahr eines Ziels hinzugefügt oder entfernt wird, basiert die Ereignisausbreitung immer auf dem Zielknoten und den Vorfahren des Ziels, die vor dem Versand ermittelt wurden.
Einige Ereignisse erfüllen möglicherweise nicht unbedingt die drei Phasen des DOM-Ereignisflusses, z. B. kann das Ereignis nur für eine oder zwei Phasen definiert werden. Beispielsweise führen Ereignisse, die in dieser Spezifikation definiert sind, immer die Erfassungs- und Zielphase durch, einige jedoch nicht die Blasenphase ("Sprudelereignisse" im Vergleich zu "nicht sprudelnden Ereignissen", siehe auch das Attribut "Event.bubbles").
quelle
Window
stattdocument
, weildocument
ist ein Kind vonWindow
?Capture Event (
useCapture = true
) vs Bubble Event (useCapture = false
)MDN-Referenz
useCapture
Parameter keine Rolle (Danke @bam und @ legend80s)stopPropagation()
stoppt den FlussDemo
Ergebnis:
Zielblase 1
(Da Capture und Bubble of Target in der Reihenfolge ihrer Registrierung ausgelöst werden, wird das Bubble-Ereignis vor dem Capture-Ereignis ausgelöst.)
Zielerfassung
quelle
Events in the target phase will trigger all listeners on an element in the order they were registered, regardless of the useCapture parameter.
Von developer.mozilla.org/en-US/docs/Web/API/EventTarget/… . Es gibt also keine Phase von "Children Capture" und "Children Bubble".Wenn Sie useCapture = true sagen, werden die Ereignisse in der Erfassungsphase von oben nach unten ausgeführt, wenn false, wird eine Blase von unten nach oben ausgeführt.
quelle
Alles dreht sich um Ereignismodelle: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow Sie können Ereignisse in der Blasen- oder Erfassungsphase erfassen. Deine Entscheidung.
Werfen Sie einen Blick auf http://www.quirksmode.org/js/events_order.html - Sie werden es sehr nützlich finden.
quelle
Codebeispiel:
Javascript-Code:
wenn beide auf false gesetzt sind
Wird ausgeführt: Wenn Sie auf Inner Div klicken, werden Warnungen wie folgt angezeigt: Div 2> Div 1
Hier wird das Skript aus dem inneren Element ausgeführt: Event Bubbling (useCapture wurde auf false gesetzt)
div 1 wird auf true und div 2 auf false gesetzt
Wird ausgeführt: Wenn Sie auf Inner Div klicken, werden Warnungen wie folgt angezeigt: Div 1> Div 2
Hier wird das Skript vom Vorfahren / äußeren Element ausgeführt: Ereigniserfassung (useCapture wurde auf true gesetzt)
div 1 wird auf false und div 2 auf true gesetzt
Wird ausgeführt: Wenn Sie auf Inner Div klicken, werden Warnungen wie folgt angezeigt: Div 2> Div 1
Hier wird das Skript aus dem inneren Element ausgeführt: Event Bubbling (useCapture wurde auf false gesetzt)
div 1 wird auf true und div 2 auf true gesetzt
Wird ausgeführt: Wenn Sie auf Inner Div klicken, werden Warnungen wie folgt angezeigt: Div 1> Div 2
Hier wird das Skript vom Vorfahren / äußeren Element ausgeführt: Ereigniserfassung, da useCapture auf true gesetzt wurde
quelle
Zusammenfassung:
Die
DOM
in:https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
funktioniert folgendermaßen:
Ein Ereignis wird auf einem Pfad von der Wurzel (
document
) des Baums zum Zielknoten ausgelöst . Der Zielknoten ist das tiefsteHTML
Element, dh das event.target. Die Ereignisverteilung (auch Ereignisausbreitung genannt) erfolgt in drei Phasen und in der folgenden Reihenfolge:document
) an die Vorfahren des Ziels an das direkte übergeordnete Element des Zielknotens gesendet.html
Zielphase befindet sich immer auf dem tiefsten Element, auf dem das Ereignis ausgelöst wurde.Beispiel:
Das obige Beispiel zeigt wirklich den Unterschied zwischen Ereignisblasenbildung und Ereigniserfassung. Beim Hinzufügen der Ereignis-Listener mit
addEventListener
gibt es ein drittes Element namens useCapture. Dies ist eineboolean
Option, beitrue
der der Ereignis-Listener die Ereigniserfassung anstelle des Ereignisblasen verwenden kann.In unserem Beispiel sehen wir, wenn wir das Argument useCapture auf setzen
false
, dass ein Ereignis sprudelt. Zuerst wird das Ereignis in der Zielphase ausgelöst (protokolliert innerBubble), und dann wird über Ereignisblasen das Ereignis im übergeordneten Element ausgelöst (protokolliert OuterBubble).Wenn wir das Argument useCapture auf setzen
true
, sehen wir, dass das Ereignis im äußeren<div>
zuerst ausgelöst wird. Dies liegt daran, dass das Ereignis jetzt in der Erfassungsphase und nicht in der Blasenphase ausgelöst wird.quelle
Angesichts der drei Phasen der Veranstaltung Reise :
useCapture
zeigt an, für die Phasen der Veranstaltung Reise wird auf:Die Quelle entspricht der zweitbesten Antwort: https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases
quelle
Die Reihenfolge der Definition ist nur wichtig, wenn sich die Elemente auf derselben Ebene befinden. Wenn Sie die Reihenfolge der Definition in Ihrem Code umkehren, erhalten Sie die gleichen Ergebnisse.
Wenn Sie jedoch die Einstellung useCapture für die beiden Ereignishandler umkehren, antwortet der untergeordnete Ereignishandler vor dem des übergeordneten Ereignisses. Der Grund dafür ist, dass der untergeordnete Ereignishandler jetzt in der Erfassungsphase ausgelöst wird, die vor der Blasenphase liegt, in der der übergeordnete Ereignishandler ausgelöst wird.
Wenn Sie useCapture für beide Ereignishandler auf true setzen - unabhängig von der Reihenfolge der Definition - wird der übergeordnete Ereignishandler zuerst ausgelöst, da er in der Erfassungsphase vor dem untergeordneten Element liegt.
Wenn Sie dagegen useCapture für beide Ereignishandler auf false setzen - wiederum unabhängig von der Reihenfolge der Definition -, wird der untergeordnete Ereignishandler zuerst ausgelöst, da er in der Bubbling-Phase vor dem übergeordneten Element steht.
quelle