Orlok: Event nicht weiterreichen stopPropagation

Beitrag lesen

Hallo Linuchs

Zunächst einmal sollte HTML und JavaScript nicht vermischt werden, das ist schlechte Praxis, also registriere deine Eventhandler nicht inline sondern im Script, vorzugsweise unter Verwendung der Methode addEventListener.

Darüber hinaus gibt es keine Eigenschaft mit dem Bezeichner childnodes, es sei denn du hättest sie selbst angelegt, was wohl eher unwahrscheinlich ist. Die von der Schnittstelle Node bereitgestellte Methode heißt childNodes; Beachte das große ‚N‘ – JavaScript ist case-sensitive.

Außerdem sollte auch JavaScript und CSS nicht vermischt werden, das ist ebenfalls schlechte Praxis. Setze also nicht das Style-Attribut des Elements sondern setze statt dessen eine Klasse und entferne sie wieder. Siehe hierzu den Artikel zu classList.

Weiterhin ist die Methode stopPropagation eine Methode der Schnittstelle Event, nicht der Schnittstelle EventTarget. Das heißt, sie wird nicht an die Elemente vererbt sondern an das Event-Objekt, welches einer als Handler registrierten Funktion bei ihrem Aufruf automatisch als erstes Argument übergeben wird.

Was du hier gemacht hast liest sich geparst etwa so:

listItem.onclick = function (event) {
  toggleDisplay(this);
};

Als Handler registriert hast du also eine anonyme Funktion, die im Kontext des Objektes ausgeführt wird, für welches du sie registriert hast. Sprich, die Variable this wird beim Aufruf mit dem Objekt initialisiert, welches das entsprechende Element repräsentiert. Das hast du ja schon ganz richtig erkannt.

Durch die Closure geht dir hier aber das Event-Objekt verloren, sodass ein Zugriff auf stopPropagation innerhalb der Funktion toggleDisplay nicht mehr möglich ist!

Statt über die Variable this kann das Objekt, in dessen Kontext der Handler ausgeführt wird, übrigens auch über die Eigenschaft currentTarget des Event-Objektes referenziert werden, weshalb der Verlust dieses Objektes schwerer wiegt als der Verlust des Kontextes.

Wenn du eine Funktion direkt als Handler registrierst, hast du Zugriff auf beides:

listItem.addEventListener('click', function (event) {
  // hier kann listItem sowohl über this
  // als auch über event.currentTarget
  // referenziert werden
});

Merke: Der Wert der Eigenschaft currentTarget ebenso wie der Wert der Variable this ist in einer direkt als Handler registrierten Funktion immer eine Referenz auf das Objekt, für welches der Handler registriert wurde.

Anders verhält es sich mit dem Wert der Eigenschaft target des Event-Objektes. Dieser enthält eine Referenz auf das Objekt, bei dem das Ereignis tatsächlich eingetreten ist.

menu.addEventListener('click', function (event) {
  // referenziere das Element, bei dem das Ereignis eingetreten ist
  var element = event.target;
});

Du brauchst nach dem Prinzip der Event Delegation für dein Menü nur einen einzigen Eventhandler für das entsprechende Ereignis registrieren und dann kannst du über event.target selektieren, was jeweils passieren soll, abhängig davon, bei welchem Zielelement das Ereignis eingetreten ist.

Hierzu würde es sich freilich anbieten, entsprechende Klassen zu definieren, um die Elemente innerhalb der Handlerfunktion entsprechend zu selektieren. Einen Aufruf von stopPropagation könntest du dir dann komplett sparen.

Viele Grüße,

Orlok

--
„Das Wesentliche einer Kerze ist nicht das Wachs, das seine Spuren hinterlässt, sondern das Licht.“ Antoine de Saint-Exupéry