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.
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.
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.
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.
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.
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.
<!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
- Einen Listener an den Streifen, dann red klicken. Der Zettel ist red. Red hat keinen eigenen Listener.
- Mit demselben Listener blue klicken. Der Zettel ist blue.
- Gold erzeugen, anhängen, klicken. Der Zettel ist gold. Der Listener saß schon am Streifen.
- 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.currentTargetlesen, obwohl du das Ticket wolltestevent.targetlesen, obwohl du den Streifen wolltest- Den Wächter vergessen, sodass
strip.click()strip schreibt - Ein
spanim Button, dann isttargetder span und die Id leer addEventListenernoch einmal an gold, undhandsals 2 zählenpreventDefaultoderstopPropagationaufrufen; 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
addEventListeneram Streifen hört jeden Button darin - Beim Klick auf red ist
event.target.idred undevent.currentTarget.idstrip - 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
Testen Sie Ihr Wissen
Fordern Sie sich mit diesem interaktiven Quiz heraus und sehen Sie, wie gut Sie das Thema verstehen
📝 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