Js-Ereignis sprudelt. JavaScript – Ereignissprudeln. Wie funktionieren die meisten davon?

💖 Gefällt es dir? Teilen Sie den Link mit Ihren Freunden

Jetzt werden wir uns einige fortgeschrittene Dinge bei der Arbeit mit dem Event-Objekt ansehen, nämlich: Bubbling und Interception sowie Event-Delegation.

Sprudelnde Ereignisse

Stellen Sie sich vor, Sie haben mehrere ineinander verschachtelte Blöcke:

innerster Block

Wenn Sie auf den innersten Block klicken, wird das onclick-Ereignis zuerst auf diesem und dann auf seinem übergeordneten Element, auf dem übergeordneten Element seines übergeordneten Elements usw. ausgelöst, bis es das body-Tag und dann das html-Tag erreicht (dann document und window ).

Und das ist logisch, denn wenn Sie auf den internen Block klicken, klicken Sie gleichzeitig auf alle externen.

Sehen wir uns das anhand des folgenden Beispiels an: Wir haben 3 Blöcke, an jeden von ihnen ist ein Onclick-Ereignis angehängt:

Klicken Sie auf den innersten roten Block – und Sie werden sehen, wie das Anklicken des roten Blocks zuerst funktioniert, dann des blauen und dann des grünen Blocks:

Dieses Verhalten wird aufgerufen durch Auftauchen Ereignisse - analog zum Aufstieg einer Luftblase vom Boden. Genau wie die Blase scheint unser Klick auf das innere Element nach oben zu schweben und jedes Mal höhere Blöcke auszulösen.

event.target

Lassen Sie uns zwei Elemente haben: ein div und einen Absatz p, der innerhalb dieses div liegt. Binden wir onlick an ein Div:

Wenn wir auf dieses Div klicken, können wir zu einem Absatz gehen oder zu einer Stelle, an der dieser Absatz nicht existiert.

Wie das sein kann – schauen Sie sich das folgende Beispiel an: grüne Farbe ist unser Div, und das blaue ist unser Absatz:

Wenn wir auf den grünen Teil klicken, klicken wir auf das Div, und wenn wir auf den blauen Teil klicken, erfolgt der Klick zuerst auf den Absatz und dann auf das Div. Da onclick jedoch speziell an das div angehängt ist, bemerken wir im Allgemeinen möglicherweise nicht das Vorhandensein des Absatzes.

Manchmal möchten wir jedoch wissen, ob der Klick direkt auf ein Div oder auf dessen untergeordneten Absatz erfolgt ist. Dabei hilft uns das Event-Objekt und seine event.target-Eigenschaft – es speichert genau das Element, in dem der Klick stattgefunden hat.

Im folgenden Beispiel haben wir ein div mit einem p darin und einem span darin.

Lassen Sie uns das Onclick-Ereignis selbst binden oberstes Element(div) und wir klicken auf verschiedene Elemente: div, p, span. Mit event.target erhalten wir das niedrigste Element, in dem das Ereignis aufgetreten ist, und zeigen seinen Namen mit tagName an.

Wenn Sie beispielsweise auf einen Span klicken, fängt das Ereignis unser Div ab (schließlich ist der Onclick daran angehängt), aber der Span befindet sich in event.target:

Klicken Sie auf verschiedene Blöcke – Sie sehen das Ergebnis:

Aufstieg stoppen

Sie wissen also bereits, dass alle Ereignisse bis ganz nach oben sprudeln (zum HTML-Tag, dann zum Dokument und dann zum Fenster). Manchmal besteht die Notwendigkeit, diesen Aufstieg zu stoppen. Jedes Element, durch das das Ereignis sprudelt, kann dies tun. Rufen Sie dazu die Methode event.stopPropagation() im Elementcode auf.

Im folgenden Beispiel funktioniert das Klicken auf den roten Block auf sich selbst, dann auf den blauen Block und das war's – der blaue Block wird nicht mehr angezeigt und der grüne Block reagiert in keiner Weise:

Klicken Sie auf den roten Block – Sie sehen das Ergebnis:

Tauchen

Neben der Entstehung von Ereignissen gibt es auch tauchen(je nach wissenschaftlichem Abfangstadium). Das bedeutet, dass das Ereignis zunächst von oben nach unten kommt (Abfangstadium), dann unser Element erreicht (Zielstadium) und erst dann anfängt aufzutauchen (Aufstiegsstadium).

Sie können einen Event-Handler nur unter Berücksichtigung der Abfangphase mit addEventListener anhängen. Dafür gibt es einen dritten Parameter: Wenn er wahr ist, wird das Ereignis in der Abfangphase ausgelöst, und wenn er falsch ist, in der Bubbling-Phase (dies ist die Standardeinstellung):

Var green = document.getElementById("green"); green.addEventListener("click", func, true); Funktion func(event) ( )

Die Phase, in der ein Ereignis aufgetreten ist, kann mithilfe der Eigenschaft event.eventPhase ermittelt werden. Es kann folgende Werte annehmen: 1 – Abfangstufe, 2 – Zielstufe, 3 – Aufstiegsstufe.

Einführung in die Delegation

Stellen wir uns eine Situation vor: Lassen Sie uns ein ul mit mehreren li haben. An jedes Li ist das folgende Ereignis angehängt: Wenn Sie auf das Li klicken, wird am Ende ein „!“ hinzugefügt.

Lassen Sie uns das Beschriebene umsetzen:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
var li = document.querySelectorAll("#ul li"); //In der Schleife hängen wir die Funktion addSign an jedes li an: for (var i = 0; i

Klicken Sie auf li – Sie werden sehen, wie am Ende ein „!“ hinzugefügt wird:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5

Lassen Sie uns jetzt auch eine Schaltfläche haben. Wenn Sie darauf klicken, wird am Ende von ul ein neues li mit dem Text „item“ hinzugefügt. Wir erleben eine Überraschung: Das gebundene Event funktioniert nicht für neue Li's! Stellen wir Folgendes sicher:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
Li hinzufügen

Klicken Sie auf die Schaltfläche, um li hinzuzufügen, und dann auf dieses neue li – es wird nicht reagiert:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
Li hinzufügen

Um das Problem zu lösen, können Sie beim Erstellen einer neuen LI die Funktion addSign über addEventListener anhängen. Lassen Sie uns Folgendes umsetzen:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
Li hinzufügen var li = document.querySelectorAll("#ul li"); für (var i = 0; i

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
Li hinzufügen

Es gibt eine zweite Möglichkeit, das Problem zu umgehen: die Delegation von Ereignissen. Lassen Sie es uns aufschlüsseln.

Event-Delegation

Die Essenz der Delegation ist wie folgt: Weisen wir ein Ereignis nicht jedem Li zu, sondern seinem übergeordneten Element – ​​in der Ul.

Gleichzeitig sollte die Funktionalität unseres Skripts erhalten bleiben: Wenn Sie auf li klicken, wird wie bisher ein „!“ am Ende hinzugefügt. Nur das Ereignis in der neuen Version wird an ul angehängt:

Var ul = document.getElementById("ul"); //Hänge das Ereignis an ul an: ul.addEventListener("click", addSign); Funktion addSign() ( )

So überprüfen wir das: Da das Ereignis an ul angehängt ist, können wir innerhalb der Funktion li mithilfe von event.target abfangen. Ich möchte Sie daran erinnern, was event.target ist – das ist genau das Tag, in dem der Klick stattgefunden hat, in unserem Fall ist es li .

Hier ist also die Lösung unseres Problems durch Delegation:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5

Ergebnis der Codeausführung:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5

Darüber hinaus funktioniert unsere Lösung auch für neue li automatisch, da das Ereignis nicht li, sondern ul zugewiesen wird:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
Li hinzufügen var ul = document.getElementById("ul"); ul.addEventListener("click", addSign); function addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; ) //Implementierung einer Schaltfläche zum Hinzufügen einer neuen Li: var button = document.getElementById("button"); button.addEventListener("click", addLi); Funktion addLi() ( var li = document.createElement("li"); li.innerHTML = "new li"; ul.appendChild(li); )

Klicken Sie auf die Schaltfläche, um li hinzuzufügen, und dann auf dieses neue li – es wird reagieren:

  • Absatz 1
  • Punkt 2
  • Punkt 3
  • Punkt 4
  • Punkt 5
Li hinzufügen

Unser Code funktioniert, aber nicht ohne Mängel. Schauen wir uns diese Mängel an und schreiben wir eine universellere Lösung.

Universelle Event-Delegation

Der Mangel unseres Codes wird deutlich, wenn in li einige verschachtelte Tags vorhanden sind. In unserem Fall seien dies die i-Tags:

In diesem Fall wird durch Drücken von „Ich“ hinzugefügt Ausrufezeichen bis zum Ende des i-Tags und nicht des li-Tags, wie wir es gerne hätten (wenn Sie außerhalb der Kursivschrift auf li klicken, ist alles in Ordnung):

  • Absatz Kursivschrift 1
  • Absatz Kursivschrift 2
  • Absatz Kursivschrift 3
  • Absatz Kursivschrift 4
  • Absatz Kursivschrift 5
var ul = document.getElementById("ul"); ul.addEventListener("click", addSign); Funktion addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; )

Klicken Sie auf Kursivschrift – Sie werden sehen, wie „!“ angezeigt wird. wird am Ende hinzugefügt (das Drücken außerhalb der Kursivschrift funktioniert einwandfrei):

Das Problem wird wie folgt behoben (die beschriebene Methode ist nicht die einzige, aber die einfachste): Mit der nächstgelegenen Methode finden wir das nächstgelegene li, das das übergeordnete Element von event.target ist, wie folgt: event.target.closest(" li") .

So funktioniert es: Wenn auf i geklickt wurde, enthält event.target dieses i und event.target.closest("li") enthält unser li, für das das Ereignis ausgelöst werden soll.

Wenn der Klick auf das Li selbst erfolgte, enthalten sowohl event.target als auch event.target.closest("li") unser Li.

Lass uns das Prüfen:

  • Absatz Kursivschrift 1
  • Absatz Kursivschrift 2
  • Absatz Kursivschrift 3
  • Absatz Kursivschrift 4
  • Absatz Kursivschrift 5
var ul = document.getElementById("ul"); ul.addEventListener("click", function(event) ( var li = event.target.closest("li"); if (li) ( //Überprüfen Sie, ob überhaupt kein li-Elternteil vorhanden ist li.innerHTML = li.innerHTML + "!"; ) ));

Ergebnis der Codeausführung:

Dabei spielt es keine Rolle, wie tief die Verschachtelung ist: Das i-Tag kann im b-Tag liegen, und das im span-Tag und erst dann in li – egal: das event.target.closest("li" )-Konstruktion findet ein übergeordnetes Element auf jeder Verschachtelungsebene.

In dieser Lektion machen wir uns mit dem Konzept des Event-Bubblings vertraut und schauen uns auch an, wie es unterbrochen werden kann. Darüber hinaus werden wir herausfinden, welche weiteren Stadien (Phasen) das Ereignis durchläuft, bevor es zu entstehen beginnt.

Ereignisblase

Wenn für ein Element ein Ereignis auftritt, beginnt es aufzutauchen, d. h. kommt bei einem Elternteil vor, dann bei einem Großelternteil usw.

Daraus folgt, dass ein von einem Element generiertes Ereignis mithilfe eines Handlers auf seinem übergeordneten Element, Großelternelement usw. abgefangen werden kann.

Wir demonstrieren die Entstehung eines Ereignisses (Blase) anhand des folgenden Beispiels:

Überschrift

Ein sehr wichtiger Text

Kapitel

Etwas Text

Restlicher Text

Schreiben wir ein kleines Skript, mit dem wir einen „Click“-Ereignishandler für alle Seitenelemente sowie für die Dokument- und Fensterobjekte hinzufügen.

document.addEventListener("DOMContentLoaded", function() ( var allElements = document.getElementsByTagName("*"); for (var i=0; i< allElements.length; i++) { allElements[i].addEventListener("click",function() {console.log(this.tagName);},false); }; document.addEventListener("click",function() {console.log(this);},false); window.addEventListener("click",function() {console.log(this);},false); });

Lassen Sie uns eine HTML-Seite erstellen und den obigen HTML-Code einfügen. Wir werden das in JavaScript geschriebene Skript vor dem schließenden Body-Tag einfügen. Öffnen Sie anschließend die neu erstellte Seite in einem Webbrowser, drücken Sie die Taste F12 und gehen Sie zur Konsole. Klicken wir nun mit der linken Maustaste in den Bereich, der zum starken Element gehört, und sehen wir, wie das Ereignis angezeigt wird.

So unterbrechen Sie das Sprudeln von Ereignissen

Der Aufstieg eines Ereignisses (Blase) kann unterbrochen werden. In diesem Fall wird dieses Ereignis nicht für übergeordnete (übergeordnete) Elemente ausgelöst. Die Methode, die die Ausbreitung eines Ereignisses (einer Blase) stoppen soll, heißt stopPropagation() .

Ändern wir beispielsweise unser obiges Beispiel so, dass das Ereignis nicht über dem Textkörper aufsteigt: document.addEventListener("DOMContentLoaded", function() ( var allElements = document.getElementsByTagName("*"); for (var i=0 ; ich

Zweifellos ist der Belag sehr praktisch und architektonisch transparent. Hören Sie nicht damit auf, es sei denn, es ist absolut notwendig.

Abrufen des Elements, das den Handler aufgerufen hat

Um das DOM-Element (Objekt) abzurufen, das den Ereignishandler aufgerufen hat, müssen Sie das Schlüsselwort this verwenden. Dieses Schlüsselwort (this) ist im Handler nur verfügbar, wenn Sie das Ereignis mit JavaScript abonnieren.

Lassen Sie uns beispielsweise in der Konsole die ID des Elements anzeigen, das den Ereignishandler aufgerufen hat:

Var myP = document.getElementById("myP"); myP.addEventListener("click",function())( //das DOM-Element abrufen, das den Event-Handler aufgerufen hat - this //seine ID abrufen und an die Konsole ausgeben console.log(this.id); ));

Sie können auch die Eigenschaft currentTarget (event.currentTarget) verwenden, um das aktuelle Element abzurufen.

Etappen (Phasen) der Veranstaltung

Bevor ein Ereignis entsteht (die Aufstiegsphase), durchläuft es zunächst zwei weitere Phasen:

  • Stufe 1 ist die Stufe des Eintauchens in das Element, das das Ereignis erzeugt hat. Diese. In diesem Stadium findet eine Bewegung von oben nach unten statt, d.h. vom Fensterobjekt zum Element. Diese Phase wird auch Abfangphase genannt.
  • Stufe 2 ist die Stufe der Zielerreichung, d.h. Element (Objekt), das das Ereignis generiert hat.

Unter Berücksichtigung aller Phasen, die eine Veranstaltung durchläuft, ergibt sich folgendes Bild:

Ändern wir das obige Beispielskript wie folgt:

Document.addEventListener("DOMContentLoaded", function() ( var allElements = document.getElementsByTagName("*"); for (var i=0; i

Der dritte Parameter der Methoden „addEventListener“ und „removeEventListener“ bestimmt die Phase, in der das Ereignis abgefangen wird. Wenn dieser Parameter wahr ist, wird das Ereignis in der Phase des Eintauchens (Abfangens) des Ereignisses abgefangen. Und wenn der Parameter false ist, wird das Ereignis in der Blasenphase abgefangen. Um ein Ereignis auf dem Ziel selbst zu verarbeiten, können Sie die Methode addEventListener entweder mit dem Wert „false“ oder „true“ verwenden.

Achtung: Während der Immersionsphase (Abfangen) können Ereignisse nur von Handlern abgefangen werden, die mit der Methode addEventListener() hinzugefügt wurden. Handler, die über andere Methoden (ein HTML-Attribut oder über JavaScript mithilfe der on[event]-Eigenschaft) hinzugefügt werden, können Ereignisse nur in der Bubbling-Phase abfangen.

Abrufen des Elements, das das Ereignis generiert hat

Um das Zielelement zu erhalten, d. h. Das Element, das das Ereignis generiert hat, muss die Target-Eigenschaft (event.target) verwenden.

Betrachten Sie das obige Beispiel, in dem wir den Inhalt des Skriptelements wie folgt ändern:

Document.addEventListener("DOMContentLoaded", function() ( var elementBody = document.body; elementBody.addEventListener("click",function())( console.log(this.tagName + " - das Element, das den Handler aufgerufen hat") ; console .log(event.currentTarget.tagName + „ – das Element, das den Handler aufgerufen hat“); console.log(event.target.tagName + „ – das Element, das das Ereignis generiert hat“); ),false); )) ;

Lassen Sie uns unser Beispiel demonstrieren, indem wir mit der linken Maustaste in den Bereich klicken, der zum starken Element gehört:

Guten Tag! In dieser Lektion möchte ich über ein so wichtiges Konzept wie das Auftauchen und Abfangen von Ereignissen sprechen. Bubbling ist ein Phänomen, bei dem das Ereignis an das übergeordnete Element weitergegeben wird, wenn Sie auf ein untergeordnetes Element klicken.

Dies kann bei der Verarbeitung großer verschachtelter Listen oder Tabellen sehr nützlich sein. Um nicht jedem Element einen Ereignishandler zuzuweisen, können Sie dem übergeordneten Element einen Handler zuweisen, und das Ereignis wird bereits an alle verschachtelten Elemente im übergeordneten Element weitergegeben. Schauen wir uns ein Beispiel an.

Dieser Handler wird ausgelöst, wenn Sie auf einen Untertag klicken oder:

Klicken Sie auf EM, der Handler auf DIV wird funktionieren

Wie Sie sehen können, wird der Handler für das div ausgelöst, wenn Sie auf ein verschachteltes em-Element klicken. Warum passiert das? Lesen Sie weiter und finden Sie es heraus.

Aufstieg

Also das Grundprinzip des Aufstiegs:

Wenn es ein Ereignis jeglicher Art gibt, spielt es keine Rolle, ob mit der Maus auf ein Element geklickt wird. Das Ereignis wird zuerst auf dem übergeordneten Element ausgelöst und dann entlang der Kette auf alle verschachtelten Elemente übertragen.

Angenommen, es gibt drei verschachtelte Elemente FORM > DIV > P mit jeweils einem Ereignishandler:

Körper * (Rand: 10 Pixel; Rand: 1 Pixel durchgehend blau;) FORM DIV

Sprudeln sorgt dafür, dass das Klicken auf das innere Element erfolgt

Ruft den Click-Handler (sofern vorhanden) zuerst im tatsächlichen Zustand auf

Dieser Vorgang wird Aufstieg genannt, weil Ereignisse vom inneren Element durch ihre Eltern nach oben zu „schweben“ scheinen, so wie eine Luftblase im Wasser nach oben schwebt, daher kann man auch die Definition von Sprudeln finden, nun ja, es ist einfach so englisches Wort sprudelnd – aufschweben.

Zugriff auf das Zielelement event.target

Um herauszufinden, bei welchem ​​Element wir dieses oder jenes Ereignis abgefangen haben, gibt es die Methode event.target. (Lesen Sie mehr über das Ereignisobjekt).

  • event.target ist das tatsächliche Quellelement, auf dem das Ereignis aufgetreten ist.
  • Dies ist immer das aktuelle Element, das das Bubbling erreicht hat und auf dem der Handler gerade ausgeführt wird.

Wenn Sie beispielsweise nur einen form.onclick-Handler installiert haben, „fängt“ dieser alle Klicks innerhalb des Formulars ab. Unabhängig davon, wo sich der Klick befindet, wird außerdem immer noch das Element angezeigt, an dem der Handler arbeitet.

Dabei:

  • this (=event.currentTarget) wird immer das Formular selbst sein, da der Handler darauf ausgelöst wurde.
  • event.target enthält einen Link zu einem bestimmten Element innerhalb des Formulars, dem am weitesten verschachtelten Element, auf das geklickt wurde.

Dies kann prinzipiell mit event.target zusammenfallen, wenn auf das Formular geklickt wird und sich keine weiteren Elemente im Formular befinden.

Aufstieg stoppen

Typischerweise geht das Ereignis-Bubbling direkt nach oben und erreicht das Stammfensterobjekt.

Es ist jedoch möglich, den Aufstieg an einem Zwischenelement zu stoppen.

Um die Ausbreitung zu stoppen, müssen Sie die Methode event.stopPropagation() aufrufen.

Schauen wir uns ein Beispiel an: Wenn auf eine Schaltfläche geklickt wird, funktioniert der Body.onclick-Handler nicht:

Klick mich

Wenn für ein Element mehrere Handler für dasselbe Ereignis installiert sind, werden alle ausgeführt, selbst wenn die Blasenbildung aufhört.

Somit verhindert stopPropagation, dass sich das Ereignis weiter ausbreitet, alle Handler funktionieren jedoch auf dem Element, nicht jedoch auf dem nächsten Element.

Um die Verarbeitung des aktuellen Elements zu stoppen, unterstützen Browser die Methode event.stopImmediatePropagation(). Diese Methode verhindert nicht nur die Blasenbildung, sondern stoppt auch die Ereignisverarbeitung für das aktuelle Element.

Tauchen

Im Standard gibt es neben dem „Aufstieg“ von Ereignissen auch einen „Tauchgang“.

Tauchen ist im Gegensatz zum Aufstieg weniger gefragt, aber es wird trotzdem nützlich sein, darüber Bescheid zu wissen.

Es gibt also 3 Phasen der Veranstaltung:

  • Das Geschehen geht von oben nach unten. Diese Phase wird als „Abfangphase“ bezeichnet.
  • Das Ereignis hat ein bestimmtes Element erreicht. Dies ist die „Zielphase“.
  • Schließlich beginnt sich das Ereignis abzuzeichnen. Dies ist die „Aufstiegsstufe“.
  • Dies wird in der Norm wie folgt demonstriert:

    Wenn Sie also auf das TD klicken, wandert das Ereignis entlang der Elternkette, zuerst nach unten zum Element („sinks“) und dann nach oben („pops up“), wobei auf dem Weg entsprechende Handler verwendet werden.

    Oben habe ich nur über den Aufstieg geschrieben, da die anderen Etappen nicht genutzt werden und von uns unbemerkt vergehen.

    Die Hundeführer wissen nichts über die Abfangphase, beginnen aber bereits beim Aufstieg mit der Arbeit.

    Und um ein Ereignis in der Abfangphase zu erfassen, müssen Sie nur Folgendes verwenden:

    • Das Argument ist wahr, dann wird das Ereignis auf dem Weg nach unten abgefangen.
    • Das Argument ist falsch, dann wird das Ereignis beim Sprudeln abgefangen.
    Beispiele

    Im Beispiel bei , ,

    Die Prozessoren sind die gleichen wie zuvor, diesmal jedoch im Immersionsstadium. Um das Abfangen in Aktion zu sehen, klicken Sie auf das darin enthaltene Element

    Die Handler arbeiten in der Reihenfolge von oben nach unten: FORM → DIV → P.

    Der JS-Code hier ist:

    Var elems = document.querySelectorAll("form,div,p"); // jedem Element in der Abfangphase einen Handler hinzufügen für (var i = 0; i< elems.length; i++) { elems[i].addEventListener("click", highlightThis, true); }


    Niemand hindert Sie daran, Handler für beide Phasen zuzuweisen, wie folgt:

    Var elems = document.querySelectorAll("form,div,p"); für (var i = 0; i< elems.length; i++) { elems[i].addEventListener("click", highlightThis, true); elems[i].addEventListener("click", highlightThis, false); }

    Klicken Sie auf das innere Element

    So sehen Sie die Reihenfolge der Ereignisse:
    Es sollte FORM → DIV → P → P → DIV → FORM sein. Beachten Sie, dass das Element

    Werde an beiden Etappen teilnehmen.

    Ergebnisse
    • Wenn ein Ereignis auftritt, wird das Element, auf dem das Ereignis aufgetreten ist, als event.target markiert.
    • Das Ereignis bewegt sich zunächst vom Dokumentstamm nach unten zu event.target und ruft dabei Handler auf, die über addEventListener(…., true) bereitgestellt werden.
    • Das Ereignis bewegt sich von event.target bis zum Anfang des Dokuments und ruft dabei Handler auf, die über addEventListener(…., false) bereitgestellt werden.

    Jeder Handler hat Zugriff auf die Ereigniseigenschaften:

    • event.target ist das tiefste Element, in dem das Ereignis tatsächlich aufgetreten ist.
    • event.currentTarget (=this) – das Element, auf dem dieser Moment Der Selbstprozessor (den das Ereignis „erreicht“ hat) wurde ausgelöst.
    • event.eventPhase – in welcher Phase der Event-Handler ausgelöst wurde (Dive = 1, Ascenden = 3).

    Die Weitergabe kann durch Aufrufen der Methode event.stopPropagation() gestoppt werden. Dies wird jedoch nicht empfohlen, da Sie das Ereignis möglicherweise für die unerwartetsten Zwecke benötigen.

    Ereignisse sind Aktionen oder Ereignisse, die in dem System, das Sie programmieren, stattfinden und über die Sie vom System informiert werden, sodass Sie bei Bedarf auf irgendeine Weise darauf reagieren können. Wenn der Benutzer beispielsweise auf eine Schaltfläche auf einer Webseite klickt, möchten Sie möglicherweise auf diese Aktion reagieren, indem Sie ein Informationsfeld anzeigen. In diesem Artikel besprechen wir einige wichtige Konzepte rund um Ereignisse und schauen uns an, wie sie in Browsern funktionieren. Dies ist keine erschöpfende Studie, sondern lediglich das, was Sie zum jetzigen Zeitpunkt wissen müssen.

    Voraussetzungen: Zielsetzung:
    Grundlegende Computerkenntnisse, grundlegendes Verständnis von HTML und CSS, erste Schritte mit JavaScript.
    Um die grundlegende Theorie von Ereignissen zu verstehen, wie sie in Browsern funktionieren und wie sich Ereignisse in verschiedenen Programmierumgebungen unterscheiden können.
    Eine Reihe glücklicher Ereignisse

    Wie oben erwähnt, handelt es sich bei Ereignissen um Aktionen oder Ereignisse, die in dem von Ihnen programmierten System stattfinden. Das System erzeugt (oder „feuert“) ein Signal, wenn ein Ereignis eintritt, und stellt außerdem einen Mechanismus bereit, mit dem eine Aktion ausgeführt werden kann automatisch übernommen (d. h. es wird Code ausgeführt), wenn das Ereignis auftritt. Wenn beispielsweise auf einem Flughafen die Landebahn für den Start eines Flugzeugs frei ist, wird dem Piloten ein Signal übermittelt, und dieser beginnt mit der Steuerung des Flugzeugs.

    Im Web werden Ereignisse innerhalb des Browserfensters ausgelöst und neigen dazu, an ein bestimmtes Element angehängt zu werden, das sich darin befindet – dies kann ein einzelnes Element, eine Gruppe von Elementen, das in der aktuellen Registerkarte geladene HTML-Dokument usw. sein das gesamte Browserfenster. Es können viele verschiedene Arten von Ereignissen auftreten, zum Beispiel:

    • Der Benutzer klickt mit der Maus über ein bestimmtes Element oder lässt den Cursor über einem bestimmten Element schweben.
    • Der Benutzer drückt eine Taste auf der Tastatur.
    • Der Benutzer ändert die Größe oder schließt das Browserfenster.
    • Ein Formular wird übermittelt.
    • Ein Video wird abgespielt, angehalten oder die Wiedergabe beendet.
    • Es ist ein Fehler aufgetreten.

    Daraus (und aus einem Blick auf die MDN-Ereignisreferenz) können Sie schließen, dass es viele Ereignisse gibt, auf die reagiert werden kann.

    Jedes verfügbare Ereignis verfügt über einen Ereignishandler, bei dem es sich um einen Codeblock (normalerweise eine JavaScript-Funktion, die Sie als Programmierer erstellen) handelt, der ausgeführt wird, wenn das Ereignis ausgelöst wird. Wenn ein solcher Codeblock so definiert ist, dass er als Reaktion auf die Auslösung eines Ereignisses ausgeführt wird, sagen wir, dass wir einen Ereignishandler registrieren. Beachten Sie, dass Event-Handler manchmal auch Event-Listener genannt werden – sie sind für unsere Zwecke weitgehend austauschbar, obwohl sie streng genommen zusammenarbeiten. Der Listener wartet auf das Eintreten des Ereignisses, und der Handler ist der Code, der als Reaktion darauf ausgeführt wird.

    Hinweis: Webereignisse sind nicht Teil der Kernsprache JavaScript – sie werden als Teil der im Browser integrierten APIs definiert.

    Ein einfaches Beispiel

    Schauen wir uns ein einfaches Beispiel an, um zu erklären, was wir hier meinen. Sie haben bereits in vielen Beispielen dieses Kurses Ereignisse und Event-Handler gesehen, aber lassen Sie uns noch einmal zusammenfassen, um unser Wissen zu festigen. Im folgenden Beispiel haben wir ein single , wodurch der Hintergrund beim Drücken eine zufällige Farbe annimmt:

    Farbe ändern

    Schaltfläche (Rand: 10px);

    Das JavaScript sieht so aus:

    Const btn = document.querySelector("button"); function random(number) ( return Math.floor(Math.random() * (number+1)); ) btn.onclick = function() ( const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; )

    In diesem Code speichern wir mithilfe der Funktion Document.querySelector() einen Verweis auf die Schaltfläche in einer Konstante namens btn . Wir definieren auch eine Funktion, die eine Zufallszahl zurückgibt. Der dritte Teil des Codes ist der Event-Handler. Die btn-Konstante zeigt auf ein Element, und dieser Objekttyp verfügt über eine Reihe von Ereignissen, die darauf ausgelöst werden können, und daher stehen Ereignishandler zur Verfügung. Wir warten auf das Auslösen des Click-Ereignisses, indem wir die Eigenschaft des Ereignishandlers onclick so einstellen, dass sie einer anonymen Funktion entspricht, die Code enthält, der eine zufällige RGB-Farbe generiert und die Hintergrundfarbe gleich setzt.

    Dieser Code wird immer dann ausgeführt, wenn das Click-Ereignis für das Element ausgelöst wird, also immer dann, wenn ein Benutzer darauf klickt.

    Die Beispielausgabe lautet wie folgt:

    Es sind nicht nur Webseiten

    Eine weitere erwähnenswerte Sache an dieser Stelle ist, dass Ereignisse nicht nur für JavaScript gelten – die meisten Programmiersprachen verfügen über eine Art Ereignismodell, und die Funktionsweise des Modells unterscheidet sich häufig von der Funktionsweise von JavaScript. Tatsächlich ist das Ereignismodell in JavaScript für Webseiten unterscheidet sich vom Ereignismodell für JavaScript, da es in anderen Umgebungen verwendet wird.

    Inline-Ereignishandler – verwenden Sie diese nicht

    Möglicherweise sehen Sie in Ihrem Code auch ein Muster wie dieses:

    Drücken Sie die Funktion bgChange() ( const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; )

    Die früheste Methode zur Registrierung von Event-Handlern im Web umfasste Event-Handler-HTML-Attribute (oder Inline-Event-Handler) wie das oben gezeigte – der Attributwert ist buchstäblich der JavaScript-Code, den Sie ausführen möchten, wenn das Ereignis auftritt. Das obige Beispiel ruft eine Funktion auf, die in einem Element auf derselben Seite definiert ist. Sie können JavaScript jedoch auch direkt in das Attribut einfügen, zum Beispiel:

    Drück mich

    Für viele der Event-Handler-Eigenschaften finden Sie HTML-Attributäquivalente. Sie sollten diese jedoch nicht verwenden, da sie als schlechte Praxis angesehen werden. Die Verwendung eines Event-Handler-Attributs mag einfach erscheinen, wenn Sie nur etwas sehr Schnelles erledigen, aber sie werden sehr schnell unüberschaubar und ineffektiv.

    Zunächst einmal ist es keine gute Idee, HTML und JavaScript zu verwechseln, da es dadurch schwieriger zu analysieren ist. Besser ist es, Ihr JavaScript an einem Ort aufzubewahren. Wenn es sich in einer separaten Datei befindet, können Sie es auf mehrere HTML-Dokumente anwenden.

    Selbst in einer einzelnen Datei sind Inline-Ereignishandler keine gute Idee. Eine Taste ist in Ordnung, aber was wäre, wenn Sie 100 Tasten hätten? Sie müssten der Datei 100 Attribute hinzufügen, was sehr schnell zu einer Wartung führen würde. Mit JavaScript könnten Sie leicht eine Event-Handler-Funktion zu allen Schaltflächen auf der Seite hinzufügen, egal wie viele es gibt, indem Sie so etwas wie verwenden Das:

    Const Buttons = document.querySelectorAll("button"); für (sei i = 0; i< buttons.length; i++) { buttons[i].onclick = bgChange; } buttons.forEach(function(button) { button.onclick = bgChange; });

    Hinweis: Durch die Trennung Ihrer Programmierlogik von Ihrem Inhalt wird Ihre Website auch suchmaschinenfreundlicher.

    addEventListener() und removeEventListener()

    Der neueste Ereignismechanismustyp ist in der Document Object Model (DOM) Level 2 Events Specification definiert, die Browsern eine neue Funktion bietet – addEventListener() . Dies funktioniert ähnlich wie die Event-Handler-Eigenschaften, die Syntax ist jedoch offensichtlich anders. Wir könnten unser zufälliges Farbbeispiel so umschreiben, dass es so aussieht:

    Const btn = document.querySelector("button"); function bgChange() ( const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; ) btn.addEventListener("click", bgChange);

    Innerhalb der Funktion addEventListener() geben wir zwei Parameter an – den Namen des Ereignisses, für das wir diesen Handler registrieren möchten, und den Code, der die Handler-Funktion umfasst, die wir als Reaktion darauf ausführen möchten. Beachten Sie, dass es durchaus angemessen ist, den gesamten Code in einer anonymen Funktion wie dieser in die Funktion addEventListener() einzufügen:

    Btn.addEventListener("click", function() ( var rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body .style.backgroundColor = rndCol; ));

    Dieser Mechanismus hat einige Vorteile gegenüber den zuvor diskutierten älteren Mechanismen. Zunächst einmal gibt es eine Gegenfunktion, „removeEventListener()“, die einen zuvor hinzugefügten Listener entfernt. Dies würde beispielsweise den im ersten Codeblock in diesem Abschnitt festgelegten Listener entfernen:

    Btn.removeEventListener("click", bgChange);

    Dies ist für einfache, kleine Programme nicht von Bedeutung, aber für größere, komplexere Programme kann es die Effizienz beim Bereinigen alter nicht verwendeter Event-Handler verbessern. Außerdem können Sie so beispielsweise dieselbe Schaltfläche verwenden, um unter verschiedenen Umständen unterschiedliche Aktionen auszuführen – Sie müssen lediglich Event-Handler nach Bedarf hinzufügen oder entfernen.

    Zweitens können Sie auch mehrere Handler für denselben Listener registrieren. Die folgenden beiden Handler würden nicht beide angewendet:

    MyElement.onclick = functionA; myElement.onclick = functionB;

    Die zweite Zeile überschreibt den in der ersten Zeile festgelegten Wert von onclick. Dies würde jedoch funktionieren:

    MyElement.addEventListener("click", functionA); myElement.addEventListener("click", functionB);

    Beide Funktionen würden nun ausgeführt, wenn auf das Element geklickt wird.

    Darüber hinaus stehen mit diesem Ereignismechanismus eine Reihe weiterer leistungsstarker Funktionen und Optionen zur Verfügung. Diese sind etwas außerhalb des Rahmens dieses Artikels, aber wenn Sie sich darüber informieren möchten, schauen Sie sich die Referenzseiten addEventListener() und removeEventListener() an.

    Welchen Mechanismus sollte ich verwenden?

    Von den drei Mechanismen sollten Sie auf keinen Fall die HTML-Event-Handler-Attribute verwenden – diese sind veraltet, und schlecht Praxis, wie oben erwähnt.

    Die anderen beiden sind zumindest für einfache Anwendungen relativ austauschbar:

    • Event-Handler-Eigenschaften haben weniger Leistung und Optionen, aber eine bessere browserübergreifende Kompatibilität (werden bereits unterstützt). Internet Explorer 8). Sie sollten beim Lernen wahrscheinlich damit beginnen.
    • DOM-Level-2-Ereignisse (addEventListener() usw.) sind leistungsfähiger, können aber auch komplexer werden und werden weniger gut unterstützt (unterstützt bereits ab Internet Explorer 9). Sie sollten auch damit experimentieren und versuchen, sie nach Möglichkeit zu nutzen.

    Die Hauptvorteile des dritten Mechanismus bestehen darin, dass Sie bei Bedarf mithilfe von „removeEventListener()“ Event-Handler-Code entfernen und bei Bedarf mehrere Listener desselben Typs zu Elementen hinzufügen können. Sie können beispielsweise addEventListener("click", function() ( ... )) für ein Element mehrmals aufrufen, wobei im zweiten Argument unterschiedliche Funktionen angegeben werden. Dies ist bei Event-Handler-Eigenschaften nicht möglich, da alle nachfolgenden Versuche, eine Eigenschaft festzulegen, frühere überschreiben, z. B.:

    Element.onclick = function1; element.onclick = function2; usw.

    Hinweis: Wenn Sie bei Ihrer Arbeit aufgefordert werden, Browser zu unterstützen, die älter als Internet Explorer 8 sind, kann es zu Schwierigkeiten kommen, da solche alten Browser andere Ereignismodelle verwenden als neuere Browser. Aber keine Angst, die meisten JavaScript-Bibliotheken (z. B. jQuery) verfügen über integrierte Funktionen, die browserübergreifende Unterschiede abstrahieren. Machen Sie sich in dieser Phase Ihrer Lernreise darüber keine allzu großen Sorgen.

    Weitere Veranstaltungskonzepte

    In diesem Abschnitt gehen wir kurz auf einige fortgeschrittene Konzepte ein, die für Veranstaltungen relevant sind. An dieser Stelle ist es nicht wichtig, diese Konzepte vollständig zu verstehen, aber sie könnten dazu dienen, einige Codemuster zu erklären, auf die Sie wahrscheinlich von Zeit zu Zeit stoßen werden.

    Ereignisobjekte

    Manchmal sehen Sie in einer Event-Handler-Funktion einen Parameter, der mit einem Namen wie event , evt oder einfach e angegeben ist. Dies wird als Ereignisobjekt bezeichnet und automatisch an Ereignishandler übergeben, um zusätzliche Funktionen und Informationen bereitzustellen. Lassen Sie uns zum Beispiel unser Beispiel für zufällige Farben noch einmal etwas umschreiben:

    Funktion bgChange(e) ( const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; e.target.style.backgroundColor = rndCol ; console.log(e); ) btn.addEventListener("click", bgChange);

    Hier können Sie sehen, dass wir ein Ereignisobjekt, e , in die Funktion einbinden und in der Funktion einen Hintergrundfarbstil für e.target festlegen – also die Schaltfläche selbst. Die Zieleigenschaft des Ereignisobjekts ist immer ein Verweis auf das Element, bei dem das Ereignis gerade aufgetreten ist. In diesem Beispiel legen wir also eine zufällige Hintergrundfarbe für die Schaltfläche fest, nicht für die Seite.

    Hinweis: Sie können für das Ereignisobjekt einen beliebigen Namen verwenden. Sie müssen lediglich einen Namen auswählen, mit dem Sie dann innerhalb der Ereignishandlerfunktion darauf verweisen können. e/evt/event werden am häufigsten von Entwicklern verwendet, da sie kurz und leicht zu merken sind. Es ist immer gut, konsequent zu sein – mit sich selbst und wenn möglich auch mit anderen.

    e.target ist unglaublich nützlich, wenn Sie denselben Event-Handler für mehrere Elemente festlegen und mit allen etwas tun möchten, wenn auf ihnen ein Ereignis auftritt. Sie könnten beispielsweise einen Satz von 16 Kacheln haben, die verschwinden, wenn Sie darauf klicken. Es ist nützlich, das Ding immer einfach so einstellen zu können, dass es verschwindet, als e.target , anstatt es auf eine schwierigere Art und Weise auswählen zu müssen. Im folgenden Beispiel (den vollständigen Quellcode finden Sie unter „utility-eventtarget.html“; hier können Sie es auch live sehen) erstellen wir 16 Elemente mit JavaScript. Anschließend wählen wir sie alle mit document.querySelectorAll() aus, durchlaufen dann jedes einzelne und fügen jedem einen Onclick-Handler hinzu, der dafür sorgt, dass beim Klicken auf jedes einzelne eine zufällige Farbe angewendet wird:

    Const divs = document.querySelectorAll("div"); für (sei i = 0; i< divs.length; i++) { divs[i].onclick = function(e) { e.target.style.backgroundColor = bgChange(); } }

    Die Ausgabe ist wie folgt (versuchen Sie, darauf herumzuklicken – viel Spaß):

    Verstecktes Beispiel Nützliches Beispiel für ein Ereignisziel div ( height: 100px; width: 25%; float: left; ) for (let i = 1; i
  • Bleistift
  • Stift
  • Radiergummi

  • Da wir nun wissen, dass jeder Klick auf die Schaltfläche über das ul.toolbar-Element angezeigt wird, hängen wir unseren Event-Handler daran an. Zum Glück haben wir es bereits:

    Var toolbar = document.querySelector(".toolbar"); toolbar.addEventListener("click", function(e) ( var button = e.target; if(!button.classList.contains("active")) button.classList.add("active"); else button.classList. entfernen("aktiv"); ));
    Wir haben jetzt viel saubereren Code und haben sogar Schleifen beseitigt! Beachten Sie jedoch, dass wir e.currentTarget durch e.target ersetzt haben. Der Grund liegt darin, dass wir Ereignisse auf einer anderen Ebene verarbeiten.

    e.target ist das eigentliche Ziel des Ereignisses, wo es seinen Weg durch das DOM findet und von dort aus sprudelt.
    e.currentTarget – das aktuelle Element, das das Ereignis verarbeitet. In unserem Fall ist dies ul.toolbar.

    Verbesserte Popup-Ereignisse Derzeit verarbeiten wir jeden Klick auf jedes Element, das über ul.toolbar angezeigt wird, aber unsere Validierungsbedingung ist zu einfach. Was würde passieren, wenn wir ein komplexeres DOM hätten, das Symbole und Elemente enthält, die nicht zum Anklicken gedacht sind?

    • Bleistift
    • Stift
    • Radiergummi

    Hoppla! Wenn wir nun auf den li.separator oder das Symbol klicken, fügen wir ihm die Klasse .active hinzu. Zumindest ist das nicht gut. Wir brauchen eine Möglichkeit, Ereignisse zu filtern, damit wir auf das benötigte Element reagieren.

    Erstellen wir hierfür eine kleine Hilfsfunktion:

    Var delegate = function(criteria, listener) ( return function(e) ( var el = e.target; do ( if (!criteria(el)) continue; e.delegateTarget = el; listener.apply(this, arguments); return; ) while((el = el.parentNode)); ); );
    Unser Assistent macht zwei Dinge. Zunächst wird jedes Element und seine übergeordneten Elemente durchlaufen und geprüft, ob sie die im Kriterienparameter übergebene Bedingung erfüllen. Wenn das Element die Anforderungen erfüllt, fügt der Helfer dem Ereignisobjekt ein Feld namens „delegateTarget“ hinzu, in dem das Element gespeichert wird, das unsere Bedingungen erfüllt. Und ruft dann den Hundeführer an. Wenn dementsprechend kein Element die Bedingung erfüllt, wird kein Handler aufgerufen.

    Wir können es so verwenden:

    Var toolbar = document.querySelector(".toolbar"); var ButtonsFilter = function(elem) ( return elem.classList && elem.classList.contains("btn"); ); var buttonHandler = function(e) ( var button = e.delegateTarget; if(!button.classList.contains("active")) button.classList.add("active"); else button.classList.remove("active" ); ); toolbar.addEventListener("click", delegate(buttonsFilter, buttonHandler));
    Genau das, was der Arzt verordnet hat: ein Event-Handler, der an ein Element angeschlossen ist und die ganze Arbeit erledigt. Dies geschieht jedoch nur für die Elemente, die wir benötigen. Und es reagiert perfekt auf das Hinzufügen und Entfernen von Objekten zum DOM.

    Zusammenfassend haben wir kurz die Grundlagen der Implementierung von Delegationsereignissen (Umgang mit Popup-Ereignissen) besprochen reines JavaScript. Das ist gut, weil wir nicht für jedes Element eine Reihe von Handlern generieren und anhängen müssen.

    Wenn ich daraus eine Bibliothek erstellen oder den Code in der Entwicklung verwenden wollte, würde ich ein paar Dinge hinzufügen:

    Hilfsfunktion, um zu überprüfen, ob ein Objekt die Kriterien in einer einheitlicheren und einheitlicheren Form erfüllt funktionale Form. Wie:

    Var Kriterien = ( isElement: function(e) ( return e exampleof HTMLElement; ), hasClass: function(cls) ( return function(e) ( returnkriterien.isElement(e) && e.classList.contains(cls); ) ) //Weitere Kriterien);
    Auch eine teilweise Nutzung des Assistenten wäre sinnvoll:

    Var partialDelgate = function(criteria) ( return function(handler) ( return delgate(criteria, handler); ) );
    Originalartikel: Delegierte JavaScript-Ereignisse verstehen
    (Vom Übersetzer: mein erster, urteile streng.)

    Viel Spaß beim Codieren!



    Freunden erzählen