mark: JS-Events: Fragen zu Ereignisphasen (Event Phases)

Guten Abend,

Beim durchlesen des entsprechenden WIKI Eintrages möchte ich gerne fragen:

Warum gibt es eine Capturing- UND eine Bubbling-Phase?

Mir fällt da konkret kein Anwendungsfall ein, bei dem ich beide benötigen würde. Ich kann mir das nur erklären, dass das irgendwie "historisch gewachsen" ist: dass zuerst die Bubbling-Phase da war und man sich später entschlossen hat Capturing zu verwenden und jetzt gibt's eben wegen Rückwärtskompatibilität beides.

Im Wiki steht weiter:

Wird bei der Registrierung eines Event-Listeners nicht explizit etwas anderes bestimmt, so bezieht sich die Registrierung also grundsätzlich nur auf die Target-Phase und, sofern der Ereignistyp über eine solche verfügt, auf die Bubbling-Phase des Ereignisses.

Ich glaube, das ist nicht richtig.

Ein Event-Listener kann im beschriebenen Fall nur durch Target, ODER (nicht "und") Bubbling ausgelöst werden.

Wenn folgendes zutrifft:

Anschließend wird, zumindest bei den allermeisten Ereignistypen, die Liste welche den Ereignispfad darstellt umgedreht, so dass nunmehr das Zielobjekt an erster Stelle und das Fensterobjekt window an letzter Stelle steht. Danach passiert das Ereignisobjekt die Objekte die den Ereignispfad konstituieren noch einmal, nur diesmal in umgekehrter Reihenfolge. Diesen Vorgang nennt man Bubbling, was sich sinngemäß in etwa als aufsteigen übersetzen lässt.

Wäre dann nicht die Target-Phase einfach nur der erste Schritt der Bubbling-Phase, selbst, wenn es keine Bubbling-Phase (keine weiteren Einträge im Event-Path) gibt?

Das ist zwar -zugegeben- Erbsenzählerei, aber dient mir und vielleicht auch jemand anderem dazu, eine klare Idee im Kopf zu haben.

In diesem Sinne möchte ich mich auch mal bedanken, für das wiki, welches mir schon öfters die Gedanken in die richtige Richtung gelenkt hat.

lg

mark

  1. Hallo

    Beim durchlesen des entsprechenden WIKI Eintrages

    den ich geschrieben und dann halb fertig liegen gelassen habe. Mea culpa! :-)

    Warum gibt es eine Capturing- UND eine Bubbling-Phase?

    Weil man Entwicklern die Wahl lassen möchte, in welcher Reihenfolge Eventhandler aufgerufen werden, die auf verschiedenen Elementen registriert wurden. Sollen zuerst die Handler aufgerufen werden, die direkt auf dem Zielelement registriert wurden und dann erst die Handler, die weiter oben in der Hierarchie auf einem Elternelement registriert wurden, oder sollen die Handler in umgekehrter Reihenfolge aufgerufen werden? Anwendungen sind vielfältig und man wird vermutlich nicht lange suchen müssen um Beispiele zu finden, wo mal das eine und mal das andere Verhalten gewünscht ist.

    Stellen wir uns etwa ein Projekt vor, bei dem eine Komponente der Seite als fertiges Skript eingebunden wird, weil man keine Zeit oder Lust hat sie selbst zu schreiben, oder weil man es ohnehin nicht besser hinbekommen würde. Warum auch immer. Nehmen wir ferner an, dass diese Komponente interaktiv ist, also auf Benutzereingaben reagiert, also Eventhandling betreibt. Nun besteht vielleicht der Wunsch, bei einem Ereignis auf der Komponente eine Aktion durchzuführen, bevor die Komponente selbst darauf reagiert. Zum Beispiel, um Benutzereingaben vorab zu validieren.

    Man bekommt aber erst Zugriff auf die Komponente, wenn die internen Handler bereits registriert wurden und da Eventhandler in der Reihenfolge ihrer Registrierung aufgerufen werden, kann man keinen Handler registrieren, der vor den internen Handlern aufgerufen wird. Es sei denn, es gibt so etwas wie eine Capturing–Phase. Diese Ereignisphase gibt uns die Möglichkeit, Eventhandler auf Elementen zu registrieren, die das Eventobjekt auf dem Hinweg zu der Komponente passiert. So kann ein Eventhandler ausgeführt werden, bevor die Komponente von dem Ereignis Kenntnis erlangt.

    Umgekehrt ist es auch denkbar, dass man auf einer Seite mehrere interaktive Elemente hat, bei denen es sinnvoll ist, Eventhandler direkt auf den Elementen zu registrieren, um beim Ereigniseintritt spezifische Aktionen auszuführen. Womöglich gibt es aber darüber hinaus noch weitere Aktionen, die für alle diese Elemente ähnlich sind oder die noch weitere Elemente betreffen und die darum bei einem Elternelement weiter oben in der Hierarchie überwacht werden sollen. Wenn nun für die allgemeine Aktion der aktuelle Zustand der Elemente benötigt wird, also die Eventhandler direkt auf den Elementen zwingend vor dem übergeordneten Eventhandler ausgeführt werden müssen, ist man froh, dass es auch eine Bubbling–Phase gibt.

    Im Wiki steht weiter:

    Wird bei der Registrierung eines Event-Listeners nicht explizit etwas anderes bestimmt, so bezieht sich die Registrierung also grundsätzlich nur auf die Target-Phase und, sofern der Ereignistyp über eine solche verfügt, auf die Bubbling-Phase des Ereignisses.

    Ich glaube, das ist nicht richtig.

    Ein Event-Listener kann im beschriebenen Fall nur durch Target, ODER (nicht "und") Bubbling ausgelöst werden.

    Ja, du hast recht. Das ist etwas unsauber formuliert. Gemeint war, dass eine Registrierung, bei der nicht ausdrücklich angegeben wird, dass die Capturing–Phase überwacht werden soll, standardmäßig für die Target– oder Bubbling–Phase des Events erfolgt. Je nach dem, ob der Eventhandler auf dem Zielelement selbst oder einem Elternelement des Zielelements registriert wird.

    Ich habe im Artikel das ‚und‘ mal durch ein ‚oder‘ ersetzt. :-)

    Wenn folgendes zutrifft:

    Anschließend wird, zumindest bei den allermeisten Ereignistypen, die Liste welche den Ereignispfad darstellt umgedreht, so dass nunmehr das Zielobjekt an erster Stelle und das Fensterobjekt window an letzter Stelle steht. Danach passiert das Ereignisobjekt die Objekte die den Ereignispfad konstituieren noch einmal, nur diesmal in umgekehrter Reihenfolge. Diesen Vorgang nennt man Bubbling, was sich sinngemäß in etwa als aufsteigen übersetzen lässt.

    Wäre dann nicht die Target-Phase einfach nur der erste Schritt der Bubbling-Phase

    Am ersten Objekt der Liste, dem Zielelement, befindet sich das Eventobjekt zu diesem Zeitpunkt ja bereits. Die Target–Phase endet und das Bubbling beginnt, wenn das Eventobjekt das Zielelement wieder verlässt.

    Das ist zwar -zugegeben- Erbsenzählerei, aber dient mir und vielleicht auch jemand anderem dazu, eine klare Idee im Kopf zu haben.

    Ich habe den Eindruck, dass du eine klare Idee davon hast. ;-)

    In diesem Sinne möchte ich mich auch mal bedanken, für das wiki, welches mir schon öfters die Gedanken in die richtige Richtung gelenkt hat.

    Das freut mich zu lesen.

    Viele Grüße,

    Orlok

    1. Vielen Dank für deine Antwort und Ausführungen.

      Du beschreibst Fälle bei denen es durchaus Sinn macht eine Capturing- und Bubble-Phase zu haben.

      So, wie ich das jetzt einordne ergibt sich der Sinn, die Möglichkeit zu haben auf Capturing und Bubbling einen Listener aus Leserlichkeit- und Vereinfachungsgründen.

      Ich glaube, das war auch der Fehler in meinem Gedankenmodell: ich habe nach einem wirklich stringenten Fall gesucht, bei dem es Capturing- und Bubbling braucht und dabei ganz übersehen, um wie vieles eleganter sich so komplexe Szenarien lösen lassen.

      Ich versuche mich zu erklären und kürze deine Beispiele (hoffentlich nicht zu stark). Deine Beispiele sind nämlich auch allesamt mit der komplementären Event-Phase realisierbar (das bestreitest du ja auch nicht).

      Capturing - Szenario: Ich will Funktionalität VOR auslösen des Events ausführen, deshalb wähle ich die Capturing Phase:

      In diesem Fall könnte ich auch einfach alle Event-Handler der Komponenten auf dem Übergeordneten Element registrieren (Bubbling) und dort meine Weichen entsprechend stellen. Das ist natürlich nicht sonderlich elegant und setzt voraus, dass ich Zeit, Lust und Geld habe die einzelnen Komponenten ggf. umzuschreiben.

      Bubbling - Szenario: Ich habe spezifische Funktionalität für und auf Komponenten. Gemeinsame Funktionalität der Komponenten, welche auf dem Elternelement "liegt".

      In diesem Fall könnte ich meine Event-Listener allesamt auf's Elternelement legen, sie mit Capturing auslösen und dann spezifisch Weichen pro Komponente legen. Auch diese Lösung kann ziemlich schnell, ziemlich "hässlich" werden.

      Wie gesagt, mein Fehler lag darin, dass ich Leserlichkeit und Vermeidung von Komplexität nicht genug Stellenwert bei meinen Überlegungen eingeräumt habe. Ich habe nach einem stringenten Fall gesucht, deshalb meine Verwirrung.

      Den stringenten Fall gibt es dann einfach nicht... Ich meine, im Extremfall könnte ich ja alle Events auf window registrieren :)

      lg

      mark

      1. ... das ist zwar OT, aber ich deponier' es trotzdem hier: Vielen Dank, dass ihr versucht, soweit eben möglich deutsche Begriffe im Wiki zu verwenden. Ich tu' mich beispielsweise mit "Ereignis-Phase" um ein Vielfaches leichter, als mit "Event-Phase". Obwohl ich beides verstehe, reicht "Event-Phase" nur bis ins Großhirn, aber "Ereignis-Phase" geht direkt in's Rückenmark über.