mitmario.dev

Das Event-Objekt

JavaScript Im Browser 3 Min Lesezeit 3 BeispieleLektion 2 von 9

Der Browser ruft deinen Handler nicht nur auf, er übergibt ihm auch etwas: ein Objekt mit allem, was er über das Ereignis weiß.

Ein Argument, das immer da ist

Der Handler bekommt genau ein Argument. Wie du es nennst, ist deine Sache, üblich sind event oder kurz e. Nimmst du es nicht entgegen, wird es trotzdem übergeben, es interessiert dich dann eben nicht.

Was darin steht, hängt vom Ereignis ab. Ein paar Angaben sind immer dabei, andere gibt es nur bei Tastatur oder Maus.

Das ganze Objekt auf einmal auszugeben, bringt dich hier nicht weiter. console.log(event) schreibt bei einem Klick PointerEvent {isTrusted: true} in die Console: den Namen seiner Bauart und ein einziges Feld. Ein Event trägt seine Angaben nämlich nicht selbst, es erbt sie, und die Console zeigt beim Aufklappen nur, was einem Objekt wirklich gehört. isTrusted ist das eine, das ihm gehört, und es sagt, ob ein Mensch das Ereignis ausgelöst hat oder Code: Bei einem knopf.click() aus Lektion 12.1 steht dort false. Im echten Browser klappt dieselbe Zeile das ganze Ding auf. Hier fragst du einzeln nach, und die nächsten Absätze zeigen, wonach sich das lohnt.

target und currentTarget

target und currentTarget
const karte = document.querySelector(".karte");
const ausgabe = document.getElementById("ausgabe");

// Der Listener hängt an der KARTE. Geklickt wird trotzdem
// das, was unter dem Zeiger liegt.
karte.addEventListener("click", (event) => {
  const zeilen = [
    `type: ${event.type}`,
    `target: ${event.target.tagName} mit Klasse "${event.target.className}"`,
    `currentTarget: ${event.currentTarget.tagName}`,
    `gleich? ${event.target === event.currentTarget}`,
  ];
  ausgabe.textContent = zeilen.join("\n");
  console.log(zeilen.join(" | "));
});

console.log("Klick auf der Seite auf verschiedene Stellen der Karte.");

Diese beiden sind der Grund, warum es diese Lektion gibt, und sie werden zuverlässig verwechselt.

event.currentTarget ist das Element, an dem der Listener hängt. Es ist genau das, was du beim addEventListener links vom Punkt geschrieben hast. Es ändert sich nie.

event.target ist das Element, auf dem das Ereignis tatsächlich passiert ist. Also das, was unter dem Zeiger lag.

Solange das Element keine Kinder hat, sind beide gleich. Sobald es welche hat, laufen sie auseinander: Bei einer Karte mit einer Überschrift und einem Symbol darin ist currentTarget die Karte, und target ist das, was du getroffen hast. Klickst du auf das Wort im Symbol, ist target das span.

Das ist kein Fehler, sondern die Grundlage von Lektion 12.5 und 12.6. Ein Ereignis passiert unten und wird oben mitbekommen.

Faustregel: Willst du wissen, wo der Listener hängt, nimm currentTarget. Willst du wissen, worauf jemand geklickt hat, nimm target.

Type, Taste, Position

Was sonst noch im Ereignis steht
const ausgabe = document.getElementById("ausgabe");

// Bei Tastatur-Ereignissen: welche Taste war es.
document.getElementById("feld").addEventListener("keydown", (event) => {
  ausgabe.textContent = `Taste: ${event.key}`;
  console.log("key:", event.key, "| Umschalt gedrückt?", event.shiftKey);
});

// Bei Maus-Ereignissen: wo im Fenster war der Zeiger.
document.getElementById("flaeche").addEventListener("click", (event) => {
  ausgabe.textContent = `Klick bei ${Math.round(event.clientX)}, ${Math.round(event.clientY)}`;
});

// Der Name des Arguments ist frei wählbar. "event" ist üblich,
// "e" sieht man genauso oft. Der Browser übergibt es immer,
// ob du es entgegennimmst oder nicht.
document.getElementById("feld").addEventListener("focus", () => {
  console.log("Ein Handler darf das Ereignis auch ignorieren.");
});

event.type ist der Name des Ereignisses als Text, also "click", "keydown" und so weiter. Das ist praktisch, wenn derselbe Handler an mehreren Ereignissen hängt.

Bei Tastatur-Ereignissen steht in event.key, welche Taste es war: "a", "Enter", "Escape", "ArrowLeft". Dazu kommen shiftKey, ctrlKey, altKey und metaKey als Wahrheitswerte für die Sondertasten.

Bei Maus-Ereignissen sagen event.clientX und event.clientY, wo im sichtbaren Bereich des Fensters der Zeiger war, gemessen von der linken oberen Ecke in Pixeln.

In denselben Pixeln sagt getBoundingClientRect(), wo ein Element liegt. document.getElementById("flaeche").getBoundingClientRect().left in der Eingabezeile der Console antwortet 16, .top antwortet 54.78125. Klickst du danach ganz oben links in die Fläche, meldet die Ausgabe ein clientX knapp über 16 und ein clientY knapp über 55: Kante und Klick in einem Maß. Das Rechteck als Ganzes zu tippen bringt dagegen wenig, getBoundingClientRect() allein antwortet DOMRect {}, aus demselben Grund wie das Event oben.

Es gibt noch deutlich mehr, und nichts davon muss man auswendig können. Die drei aus dem ersten Beispiel decken den Alltag ab.

Und this

this im Handler, und warum es zwei Antworten gibt
// In einer klassischen Funktion setzt der Browser this auf
// currentTarget, also auf das Element mit dem Listener.
document.getElementById("klassisch").addEventListener("click", function (event) {
  console.log("this ist:", this.tagName, this.id);
  console.log("gleich currentTarget?", this === event.currentTarget);
});

// Eine Arrow Function bringt ihr this von außen mit und
// lässt es sich nicht setzen. Hier oben ist das das Fenster.
document.getElementById("pfeil").addEventListener("click", (event) => {
  console.log("this ist:", this === window ? "window" : this);
  console.log("gleich currentTarget?", this === event.currentTarget);
  console.log("currentTarget aber schon:", event.currentTarget.id);
});

console.log("Drück beide Knöpfe und vergleich die Ausgaben.");

In einer klassischen Funktion setzt der Browser this auf currentTarget. Das ist praktisch und der Grund, warum man in älterem Code oft this.classList.add(...) sieht.

In einer Arrow Function passiert das nicht. Sie bringt ihr this von dort mit, wo sie geschrieben wurde, und lässt es sich von niemandem setzen. Auf oberster Ebene eines Skripts ist das das Fenster.

Das ist genau der Unterschied aus Lektion 7.3, nur an einer neuen Stelle. Und er ist ein Grund weniger, this zu benutzen: event.currentTarget funktioniert in beiden Fällen gleich.

In diesem Kurs stehen Handler deshalb als Arrow Function da, und wo das Element gebraucht wird, steht event.currentTarget. Das ist eine Angabe mehr zu tippen und eine Verwechslung weniger.

Zum Mitnehmen

target ist, wo es passiert ist. currentTarget ist, wo der Listener hängt. Bei einem Knopf mit einem Symbol darin sind das zwei verschiedene Elemente.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.