Wie funktionieren mehrere addEventListener in JavaScript?

9

Es gibt 2 Skripte in einem Dokument

%Vor%

Um sicherzustellen, dass mein Klickereignis nicht von einem anderen Skript überschrieben wird, wechselte ich zu addEventListener .

%Vor%

Jetzt habe ich eine andere Frage. Da return false im zweiten Code nach alert definiert ist, wie verhindert es nicht, dass der Alarm aufgerufen wird?

Was ist, wenn ich möchte, dass mein Skript die totale Kontrolle über das Klick-Ereignis erhält (wie zum Beispiel die Rückgabe von "false" die ganze Zeit ohne Berücksichtigung von Ereignissen, die in anderen Skripten definiert sind)?

    
user1643156 29.04.2013, 07:48
quelle

1 Antwort

43
  

Was ist, wenn ich möchte, dass mein Skript die totale Kontrolle über das Klick-Ereignis erhält (wie zum Beispiel die Rückgabe von "false" die ganze Zeit ohne Berücksichtigung von Ereignissen, die in anderen Skripten definiert sind)?

Wenn Sie Ihren Handler zuerst registrieren können, bevor sie dies tun, können Sie das tun, vorausgesetzt, der von Ihnen verwendete Browser implementiert DOM3-Ereignisse korrekt (was wahrscheinlich ist, wenn es IE8 oder früher ist).

Hier sind (mindestens) vier Dinge beteiligt: ​​

  1. Verhindert den Standard.

  2. Die Weitergabe an Vorfahrelemente wird gestoppt.

  3. Beenden des Aufrufs anderer Handler für das selbe -Element.

  4. Die Reihenfolge, in der Handler aufgerufen werden.

In Reihenfolge:

1. Den Standard verhindern

Dies ist return false von einem DOM0-Handler. (Details: Die Geschichte bei der Rückkehr Falsch . ) Das Äquivalent in DOM2 und DOM3 ist preventDefault :

%Vor%

Das Verhindern des Standards ist möglicherweise nicht alles, was für das, was Sie tun, relevant ist, aber da Sie return false in Ihrem DOM0-Handler verwendet haben, und das den Standard verhindert, füge ich es hier der Vollständigkeit halber ein.

>

2. Die Weitergabe an Vorfahrenelemente stoppen

DOM0-Handler haben keine Möglichkeit, dies zu tun. DOM2-Elemente tun dies über stopPropagation :

%Vor%

Aber stopPropagation verhindert nicht, dass andere Handler auf demselben Element aufgerufen werden. Aus die Spezifikation :

  

Die Methode stopPropagation verhindert die weitere Verbreitung eines Ereignisses während des Ereignisflusses. Wenn diese Methode von EventListener aufgerufen wird, wird das Ereignis nicht mehr durch den Baum übertragen. Das Ereignis wird den Versand an alle Listener im aktuellen EventTarget abschließen, bevor der Ereignisfluss beendet wird.

(Mein Schwerpunkt.)

3. Andere Handler auf dem selben -Element davon abhalten,

genannt zu werden

Das ist natürlich für DOM0 nicht aufgekommen, weil andere Handler für dasselbe Ereignis auf demselben Element nicht sein konnten . : -)

Soweit mir bekannt ist, gibt es keine Möglichkeit, dies in DOM2 zu tun, aber DOM3 gibt uns stopImmediatePropagation :

%Vor%

Einige Bibliotheken bieten diese Funktion (auch auf Nicht-DOM3-Systemen wie IE8) für Handler, die über die Bibliothek angeschlossen sind, siehe unten.

4. Die Reihenfolge, in der Handler aufgerufen werden

Auch hier ist nichts mit DOM0 zu tun, weil es keine anderen Handler geben konnte.

In DOM2 sagt die Spezifikation explizit , dass die Reihenfolge, in der die an ein Element angehängten Handler aufgerufen werden, nicht garantiert ist. aber DOM3 ändert das und sagt, dass Handler in der Reihenfolge aufgerufen werden, in der sie registriert sind.

Zuerst von DOM2 Abschnitt 1.2.1 :

  

Obwohl alle EventListeners auf der EventTarget garantiert von jedem Ereignis ausgelöst werden, das von dieser EventTarget empfangen wird, wird keine Angabe gemacht, in welcher Reihenfolge sie das Ereignis in Bezug auf die andere erhalten werden EventListeners auf dem EventTarget .

Aber dies wird durch DOM3 Abschnitt 3.1 ersetzt:

>
  

Als nächstes muss die Implementierung die Event-Listener des aktuellen Ziels bestimmen. Dies muss die Liste aller Ereignis-Listener sein, die auf dem aktuellen Ziel in der Reihenfolge der Registrierung registriert wurden .

(Mein Schwerpunkt.)

Einige Bibliotheken garantieren die Reihenfolge, vorausgesetzt, Sie verbinden die Ereignisse mit der Bibliothek.

Es ist auch erwähnenswert, dass in Microsoft's Vorgänger zu DOM2 (z. B. attachEvent ) das Gegenteil von DOM3s Reihenfolge war: Die Handler wurden in umgekehrter Reihenfolge der Registrierung aufgerufen.

Wenn Sie # 3 und # 4 zusammen verwenden, können Sie zuerst Ihren Handler registrieren, dann wird er zuerst aufgerufen, und Sie können stopImmediatePropagation verwenden, um zu verhindern, dass andere Handler angerufen werden. Vorausgesetzt, der Browser implementiert DOM3 korrekt.

All das (einschließlich der Tatsache, dass IE8 und früher nicht einmal DOM2-Ereignisse implementieren, noch viel weniger DOM3) ist einer der Gründe, warum Benutzer Bibliotheken wie jQuery verwenden, von denen einige die Reihenfolge garantieren (solange alles funktioniert) ihre Handler über die betreffende Bibliothek) und bieten Möglichkeiten an, um auch andere Handler auf dem gleichen Element anzuhalten, das angerufen wird. (Bei jQuery beispielsweise ist die Reihenfolge die Reihenfolge, in der sie angefügt wurden, und Sie können stopImmediatePropagation verwenden, um Aufrufe an andere Handler zu stoppen.Aber ich versuche nicht, jQuery hier zu verkaufen, nur zu erklären, dass einige Bibliotheken mehr Funktionalität bieten als die grundlegenden DOM-Sachen.)

    
T.J. Crowder 29.04.2013, 07:51
quelle