365 Stimmen

Der Parameter useCapture in addEventListener kann nicht verstanden werden

Ich habe den Artikel gelesen unter https://developer.mozilla.org/en/DOM/element.addEventListener aber unfähig zu verstehen useCapture Attribut. Es gibt eine Definition:

Bei "true" zeigt useCapture an, dass der Benutzer die Erfassung einleiten möchte. Nach dem Einleiten der Erfassung werden alle Ereignisse des angegebenen Typs an den registrierten Listener weitergeleitet, bevor sie an alle darunter liegenden EventTargets im DOM-Baum weitergeleitet werden. Ereignisse, die sich im Baum nach oben bewegen, lösen keinen Listener aus, der für die Verwendung von Capture bestimmt ist.

In diesem Code wird das übergeordnete Ereignis vor dem untergeordneten Ereignis ausgelöst, so dass ich nicht in der Lage bin, das Ereignis zu verstehen. Dokument-Objekt hat usecapture wahr und Kind div hat usecapture falsch gesetzt und Dokument usecapture gefolgt ist.so warum Dokument-Eigenschaft über Kind bevorzugt wird.

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>

418voto

Rob W Punkte 327048

Ereignisse können bei zwei Gelegenheiten aktiviert werden: Am Anfang ("capture") und am Ende ("bubble"). Ereignisse werden in der Reihenfolge ausgeführt, in der sie definiert wurden. Angenommen, Sie definieren 4 Ereignis-Listener:

window.addEventListener("click", function(){console.log(1)}, false);
window.addEventListener("click", function(){console.log(2)}, true);
window.addEventListener("click", function(){console.log(3)}, false);
window.addEventListener("click", function(){console.log(4)}, true);

Die Protokollmeldungen werden in dieser Reihenfolge angezeigt:

  • 2 (zuerst definiert, unter Verwendung von capture=true )
  • 4 (definiert als zweites mit capture=true )
  • 1 (erstes definiertes Ereignis mit capture=false )
  • 3 (zweites definiertes Ereignis mit capture=false )

325voto

lax4mike Punkte 4745

Ich finde dieses Diagramm sehr nützlich, um die Phasen Einfangen/Ziel/Blase zu verstehen: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

Im Folgenden finden Sie einen Auszug aus dem Link.

Phasen

Das Ereignis wird auf einem Pfad von der Wurzel des Baums zu diesem Zielknoten ausgelöst. Es kann dann lokal auf der Ebene des Zielknotens oder von den Vorfahren des Zielknotens, die höher im Baum liegen, behandelt werden. Die Ereignisweiterleitung (auch Ereignisfortpflanzung genannt) erfolgt in drei Phasen und in der folgenden Reihenfolge:

  1. Die Erfassungsphase: Das Ereignis wird an die Vorfahren des Ziels weitergeleitet von der Wurzel des Baums bis zum direkten Elternteil des Zielknotens.
  2. Die Zielphase: Das Ereignis wird an den Zielknoten weitergeleitet.
  3. Die Bubbling-Phase: Das Ereignis wird an die Vorfahren des Ziels weitergeleitet Vorfahren des Zielknotens vom direkten Elternteil des Zielknotens bis zur Wurzel des des Baums.

graphical representation of an event dispatched in a DOM tree using the DOM event flow

Die Vorfahren des Ziels werden vor dem ersten Versand des Ereignisses bestimmt. Wenn der Zielknoten während der Versendung entfernt wird oder ein Vorfahr des Ziels hinzugefügt oder entfernt wird, basiert die Ereignisausbreitung immer auf dem Zielknoten und den vor der Versendung ermittelten Vorfahren des Ziels.

Einige Ereignisse müssen nicht unbedingt die drei Phasen des DOM-Ereignisflusses erfüllen, z. B. könnte das Ereignis nur für eine oder zwei Phasen definiert sein. Die in dieser Spezifikation definierten Ereignisse erfüllen beispielsweise immer die Phasen "Capture" und "Target", aber einige erfüllen nicht die Phase "Bubbling" ("bubbling events" versus "non-bubbling events", siehe auch das Attribut Event.bubbles).

100voto

Steely Wing Punkte 14161

Ereignis einfangen ( useCapture = true ) gegen Bubble Event ( useCapture = false )

MDN-Referenz

  • Das Erfassungsereignis wird vor dem Blasenereignis ausgelöst.
  • Die Reihenfolge der Ereignisausbreitung ist
    1. Erfassen der Eltern
    2. Kinder einfangen
    3. Zielerfassung und Zielblase
      • In der Reihenfolge, in der sie registriert wurden
      • Wenn das Element das Ziel des Ereignisses ist, useCapture Parameter spielt keine Rolle (Danke @bam und @legend80s)
    4. Kinder Bubble
    5. Parent Bubble
  • stopPropagation() stoppt den Fluss

use Capture flow

Demo

Ergebnis:

  1. Erfassen der Eltern

  2. Zielblase 1

    (Weil Capture und Bubble of Target in der Reihenfolge ausgelöst werden, in der sie registriert wurden, also wird das Bubble-Ereignis vor dem Capture-Ereignis ausgelöst)

  3. Zielerfassung

  4. Zielblase 2

  5. Parent Bubble

    var parent = document.getElementById('parent'), target = document.getElementById('target');

    target.addEventListener('click', function (e) { console.log('Target Bubble 1'); // e.stopPropagation(); }, false);

    target.addEventListener('click', function (e) { console.log('Target Capture'); // e.stopPropagation(); }, true);

    target.addEventListener('click', function (e) { console.log('Target Bubble 2'); // e.stopPropagation(); }, false);

    parent.addEventListener('click', function (e) { console.log('Parent Capture'); // e.stopPropagation(); }, true);

    parent.addEventListener('click', function (e) { console.log('Parent Bubble'); // e.stopPropagation(); }, false);

    <div id="parent"> <button id="target" style="padding: 1em 0.8em;"> Trigger event </button> </div>

25voto

sushil bharwani Punkte 28837

Wenn Sie useCapture = true angeben, werden die Ereignisse in der Erfassungsphase von oben nach unten ausgeführt, wenn Sie false angeben, wird eine Blase von unten nach oben erstellt.

22voto

Willem van der Veen Punkte 26043

Zusammenfassung:

En DOM Spezifikation beschrieben in:

https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases

funktioniert auf folgende Weise:

Ein Ereignis wird auf einem Pfad von der Wurzel ( document ) des Baumes zum Zielknoten . Der Zielknoten ist der am tiefsten liegende HTML Element, d.h. das event.target. Die Ereignisauslösung (auch Ereignisfortpflanzung genannt) erfolgt in drei Phasen und in der folgenden Reihenfolge:

  1. Die Erfassungsphase: wird das Ereignis an die Vorfahren des Ziels von der Wurzel des Baums aus weitergeleitet ( document ) auf den direkten Elternteil des Zielknotens.
  2. Die Zielphase: wird das Ereignis an den Zielknoten weitergeleitet. Die Zielphase liegt immer auf dem tiefsten html Element, bei dem das Ereignis ausgelöst wurde.
  3. Die Blasenbildungsphase: wird das Ereignis an die Vorfahren des Zielknotens vom direkten Elternteil des Zielknotens bis zur Wurzel des Baums weitergeleitet.

Event bubbling, event capturing, event target

Beispiel:

// bubbling handlers, third argument (useCapture) false (default)
document.getElementById('outerBubble').addEventListener('click', () => {
  console.log('outerBubble');
}, false)

document.getElementById('innerBubble').addEventListener('click', () => {
  console.log('innerBubble');
}, false)

// capturing handlers, third argument (useCapture)  true
document.getElementById('outerCapture').addEventListener('click', () => {
  console.log('outerCapture');
}, true)

document.getElementById('innerCapture').addEventListener('click', () => {
  console.log('innerCapture');
}, true)

div:hover{
  color: red;
  cursor: pointer;
}

<!-- event bubbling -->
<div id="outerBubble">
  <div id="innerBubble">click me to see Bubbling</div>
</div>

<!-- event capturing -->
<div id="outerCapture">
  <div id="innerCapture">click me to see Capturing</div>
</div>

Das obige Beispiel verdeutlicht den Unterschied zwischen Event Bubbling und Event Capturing. Beim Hinzufügen der Ereignis-Listener mit addEventListener gibt es ein drittes Element namens useCapture. Dieses a boolean die bei Einstellung auf true ermöglicht es dem Ereignis-Listener, anstelle von Event-Bubbling Event-Capturing zu verwenden.

Wenn wir in unserem Beispiel das Argument useCapture auf false sehen wir, dass das Event Bubbling stattfindet. Zunächst wird das Ereignis in der Zielphase ausgelöst (logs innerBubble), und dann wird über Event Bubbling das Ereignis im übergeordneten Element ausgelöst (logs outerBubble).

Wenn wir das Argument useCapture auf true sehen wir, dass das Ereignis in der äußeren <div> wird zuerst abgefeuert. Dies liegt daran, dass das Ereignis jetzt in der Erfassungsphase und nicht in der Blasenbildungsphase ausgelöst wird.

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