Lädt...

Event-Delegation

Am Schalter hängt ein Streifen. Der Elternknoten ist #strip. Zwei Buttons sitzen schon darauf: #red mit dem Text red und #blue mit dem Text blue. Darunter sagt #note noch blank.
Du musst nicht an jeden Button einen eigenen Listener hängen. Einmal addEventListener auf den Streifen. Ein Klick auf einen Button darin steigt zum Streifen auf. event.target ist der Button. event.currentTarget ist der Streifen, also das Element, an dem dieser Listener sitzt.
Das goldene Ticket ist noch nicht im Markup. Die Seite erzeugt #gold erst nach dem Speichern des Listeners, hängt es an und klickt es. Dieselbe Funktion läuft trotzdem. Der Zettel wird gold. Das Skript klickt red, dann blue, dann gold. addEventListener lief einmal, also ist hands gleich 1. Die Zeile unter dem Streifen lautet red / blue / gold / 1. Die Buttons haben type="button". Hier gibt es kein preventDefault und kein stopPropagation. Das war die Tafelseite, und dort kam nach dem Listener kein Kind dazu.

Ein Listener für jedes Ticket

Die Tafelseite nannte den Parameter event und las type, target und currentTarget an einem Link in der Wand. Die Zeile war click / seal / plaque / true / quiet. Der Garderobenhaken speicherte wool und silk ohne Parameter. Die Zeile war wool silk / 2 / peg. Hier bleibt der Parameter event, aber target hat eine andere Aufgabe: welcher Kindknoten geklickt wurde, auch einer, den es vorher nicht gab.
getElementById gibt dir nur den Streifen, den roten Button, den blauen Button und den Zettel. Gold entsteht mit createElement. Ein Listener an red und einer an blue verpassen gold, außer du hängst nach appendChild noch einmal einen an. Ein Listener am Streifen braucht diese zweite Anmeldung nicht. Lies currentTarget in der Funktion. Nach der Rückkehr ist die Eigenschaft null.

Was der Streifen festhält

Der Zettel beginnt mit blank. Die Beschriftung bleibt red und blue, gold kommt später. Lies die Zeilen der Tabelle der Reihe nach. Jedes Stück startet mit dem Streifen aus zwei Buttons, außer die Seitenzeile, das ist die Demo unten. Die Demo ruft addEventListener einmal auf.

📊 Was der Streifen festhält

Moment Was du liest Zetteltext Leicht verwechselt
Listener am Streifen, Klick auf red event.target.id red currentTarget lesen, das ist strip
derselbe Klick, currentTarget lesen event.currentTarget.id strip die Ticket-Id lesen
derselbe Listener, Klick auf blue event.target.id blue blue einen eigenen Listener geben
gold nach dem Listener erzeugt, dann geklickt event.target.id gold der neue Button bleibt stumm
Klick auf den Streifen selbst, mit Wächter der Zettel skip die Id strip schreiben
Seitenskript die Zeile red / blue / gold / 1 die Tafelzeile, oder zuletzt 3

Ein Klick auf einen Button ist ein Ereignis. target bleibt dieser Button für jeden Listener auf dem Weg. Hier gibt es einen Listener, am Streifen, also ist currentTarget während der Funktion der Streifen. Der Klick kommt an, weil niemand stopPropagation aufruft. Die Tafelseite hat den Weg abgeschnitten. Diese Seite nicht.
preventDefault gilt für eine Standardaktion des Browsers, etwa einen Link, der die Seite verlässt. Das hier sind Buttons, keine Links. preventDefault wegzulassen ist die ganze Seite, keine vergessene Zeile.
Sind event.target und event.currentTarget derselbe Knoten, landete der Klick auf dem Streifen, nicht auf einem Button. Die Funktion schreibt skip und behandelt das Papier nicht als Ticket. seen.join(" / ") verbindet nur Ids, die schon in seen stehen. hands kommt danach. Das letzte Token ist also, wie oft addEventListener lief, nicht wie viele Tickets geklickt wurden.

Das Ticket unter dem Klick

Der Listener sitzt am Streifen. Die Funktion nennt den Parameter event und schreibt event.target.id auf den Zettel. Dann klickt die Seite red. Sie ruft addEventListener nicht auf red auf.

Das Ticket lesen

javascript
let strip = document.getElementById("strip");
let note = document.getElementById("note");
function take(event) {
note.textContent = event.target.id;
}
strip.addEventListener("click", take);
document.getElementById("red").click();
console.log(note.textContent);

Die Ausgabe ist red. Das Element des Listeners ist der Streifen. target meldet nicht den Elternknoten. Es meldet den Button unter dem Klick.

Wem der Listener gehört

Frischer Streifen, derselbe Listener, derselbe Klick auf red. Der Zettel schreibt beide Ids, zuerst target, dann currentTarget.

Beide Ids lesen

javascript
let strip = document.getElementById("strip");
let note = document.getElementById("note");
function take(event) {
note.textContent = event.target.id + " " + event.currentTarget.id;
}
strip.addEventListener("click", take);
document.getElementById("red").click();
console.log(note.textContent);

Die Ausgabe ist red strip. Das erste Wort ist das Ticket. Das zweite ist das Element, dem dieser Listener gehört. Läge der Listener auf red selbst und du klicktest red, käme red red. Diese Lesung nutzt den Streifen, deshalb unterscheiden sich die Ids.

Das Ticket, das schon daneben lag

Wieder ein frischer Streifen. Ein Listener, weiter nur am Streifen. Diesmal ist der Klick blue. Blue stand von Anfang an im Markup. Einen eigenen Listener hat es nicht.

Das Nachbarticket hören

javascript
let strip = document.getElementById("strip");
let note = document.getElementById("note");
function take(event) {
note.textContent = event.target.id;
}
strip.addEventListener("click", take);
document.getElementById("blue").click();
console.log(note.textContent);

Die Ausgabe ist blue. Ein addEventListener hat beide Buttons abgedeckt, die schon im Streifen lagen. Blue hat red nicht ersetzt. Red brauchte keinen zweiten Aufruf.

Ein später gedrucktes Ticket

Zuerst wird der Listener gespeichert. Dann baut die Seite einen Button, setzt die Id auf gold, type auf button, den Text auf gold und hängt ihn an den Streifen. Erst danach klickt sie gold.

Ein späteres Ticket hören

javascript
let strip = document.getElementById("strip");
let note = document.getElementById("note");
function take(event) {
note.textContent = event.target.id;
}
strip.addEventListener("click", take);
let gold = document.createElement("button");
gold.id = "gold";
gold.type = "button";
gold.textContent = "gold";
strip.appendChild(gold);
gold.click();
console.log(note.textContent);

Die Ausgabe ist gold. Gold gab es nicht, als addEventListener lief. Der Klick steigt von gold zum Streifen, und target ist gold. Du hängst keinen Listener an gold.

Ein Klick auf das Papier

Der Streifen ist selbst ein klickbarer Knoten. Ist das target der Klick auf den Streifen, gibt es keine Ticket-Id zum Behalten. Die Funktion vergleicht target mit currentTarget. Sind sie gleich, wird der Zettel skip.

Klick auf den Streifen ignorieren

javascript
let strip = document.getElementById("strip");
let note = document.getElementById("note");
function take(event) {
if (event.target === event.currentTarget) {
note.textContent = "skip";
return;
}
note.textContent = event.target.id;
}
strip.addEventListener("click", take);
strip.click();
console.log(note.textContent);

Die Ausgabe ist skip. Sowohl target als auch currentTarget sind der Streifen, also lehnt der Wächter das Papier ab. Ein Klick auf red schreibt weiter red, weil die beiden Verweise verschieden sind. Ohne den Wächter würde strip.click() die Id strip auf den Zettel schreiben.

Die Zeile unter dem Streifen

Das Skript steht am Ende von body, nachdem Streifen und Absätze da sind. Ein Listener wird gespeichert, hands wird 1. Red wird geklickt, dann blue. Jede Ticket-Id wandert nach seen. Gold wird erzeugt, angehängt und geklickt, also wandert auch gold nach seen. Die Zeile entsteht nach diesem dritten Klick. Die Seite klickt den Streifen selbst nie, deshalb steht skip nicht in der Zeile.

Seitendemo — Ticketstreifen

html
<!DOCTYPE html>
<html>
<head>
<title>event-delegation — page</title>
</head>
<body>
<div id="strip">
<button id="red" type="button">red</button>
<button id="blue" type="button">blue</button>
</div>
<p id="note">blank</p>
<p id="line">…</p>
<script>
let strip = document.getElementById("strip");
let note = document.getElementById("note");
let seen = [];
let hands = 0;
function take(event) {
if (event.target === event.currentTarget) {
note.textContent = "skip";
return;
}
note.textContent = event.target.id;
seen.push(event.target.id);
}
strip.addEventListener("click", take);
hands = hands + 1;
document.getElementById("red").click();
document.getElementById("blue").click();
let gold = document.createElement("button");
gold.id = "gold";
gold.type = "button";
gold.textContent = "gold";
strip.appendChild(gold);
gold.click();
document.getElementById("line").textContent =
seen.join(" / ") + " / " + hands;
</script>
</body>
</html>

Die Zeile lautet red / blue / gold / 1. Die drei Ids sind die geklickten Tickets, in dieser Reihenfolge. Das letzte Token ist hands. addEventListener lief einmal, also ist das Token 1, nicht 3. Der Zettel endet auf gold, weil gold der letzte Klick war. Das Wort blank ist weg. skip kommt nicht vor. Tafelzeile und Hakenzelle sind andere Seiten.
Ein Button, der nur Text hält, lässt event.target auf dem Button, die id ist also red, blue oder gold. Ein span im Button kann den Klick auffangen. Der span hat keine Id. Diese Seite macht das nicht.

Am Schalter

  1. Einen Listener an den Streifen, dann red klicken. Der Zettel ist red. Red hat keinen eigenen Listener.
  2. Mit demselben Listener blue klicken. Der Zettel ist blue.
  3. Gold erzeugen, anhängen, klicken. Der Zettel ist gold. Der Listener saß schon am Streifen.
  4. Den Streifen selbst klicken. Mit dem Wächter ist der Zettel skip. Dann die Seitenzeile lesen: red / blue / gold / 1.

Was am Schalter schiefgeht

Die Beschriftung sagt weiter red, blue und gold. Der Zettel ist nicht das Wort Ticket.

  • Ein Listener an red und einer an blue, dann die Überraschung, dass gold stumm bleibt
  • event.currentTarget lesen, obwohl du das Ticket wolltest
  • event.target lesen, obwohl du den Streifen wolltest
  • Den Wächter vergessen, sodass strip.click() strip schreibt
  • Ein span im Button, dann ist target der span und die Id leer
  • addEventListener noch einmal an gold, und hands als 2 zählen
  • preventDefault oder stopPropagation aufrufen; das war die Tafelseite
  • Erwarten, das Funktionsargument sei das Button-Element
  • Die Zeile als click / seal / plaque / true / quiet lesen, oder als wool silk / 2 / peg
  • Das letzte Token als 3 lesen, weil drei Tickets geklickt wurden

Das bleibt

  • Ein addEventListener am Streifen hört jeden Button darin
  • Beim Klick auf red ist event.target.id red und event.currentTarget.id strip
  • Derselbe Listener schreibt blue, wenn blue geklickt wird
  • Gold, nach dem Listener erzeugt, schreibt trotzdem gold
  • Ein Klick auf den Streifen selbst schreibt mit dem Wächter skip
  • Die Seitenzeile lautet red / blue / gold / 1

🧠 Testen Sie Ihr Wissen

Bereit zum Start

Testen Sie Ihr Wissen

Fordern Sie sich mit diesem interaktiven Quiz heraus und sehen Sie, wie gut Sie das Thema verstehen

❓
8
Fragen
🎯
70%
Zum Bestehen
♾️
∞
Zeit
🔄
∞
Versuche

📝 Anweisungen

  • Lesen Sie jede Frage sorgfältig
  • Wählen Sie die beste Antwort für jede Frage
  • Sie können das Quiz so oft wiederholen, wie Sie möchten
  • Ihr Fortschritt wird oben angezeigt