Sieh im Live-Log, wie Events ausgelöst werden, und kopiere dann addEventListener-Muster für click, submit, scroll, Delegation, once, passive und das Aufräumen mit AbortController.
Ein Event Listener ist eine Funktion, die der Browser aufruft, wenn mit einem Element etwas passiert, etwa ein Klick, das Absenden eines Formulars oder ein Scrollen. Du hängst ihn mit element.addEventListener(type, handler, options) an. Das Options-Objekt aktiviert once, passive, capture oder ein Abort-Signal, und removeEventListener entfernt dieselbe Funktion später wieder.
Optionen von addEventListener
Option
Standard
Wirkung
Entfernt den Listener nach seinem ersten Aufruf automatisch
false (true für wheel und touch auf window, document und body)
Verspricht, preventDefault nicht aufzurufen, damit das Scrollen nie warten muss
Läuft auf dem Weg hinunter zum Ziel statt auf dem Weg zurück nach oben
Ein AbortSignal, ein Abbruch entfernt den Listener
Events sind leichter zu verstehen, wenn du sie sehen kannst. Das Event-Log unten zeichnet jeden Listener-Aufruf in einem kleinen Testbereich auf. So kannst du klicken, tippen, absenden und scrollen und dabei die Reihenfolge, das Ziel und die Wirkung jeder Option beobachten. Danach kopierst du die Muster für die Aufgaben, die du wirklich hast.
Nutze die Bedienelemente im Testbereich: Klicke auf die Buttons, tippe in das Feld, sende das Formular ab und scrolle in der Box.
Jeder Listener-Aufruf erscheint im Log mit seinem Event-Typ, dem Element, das ihn ausgelöst hat, und dem Element, das ihn verarbeitet hat.
Aktiviere once, um zu sehen, wie ein Listener nach einem Aufruf verschwindet, oder deaktiviere die Delegation, damit die Liste Klicks pro Eintrag verarbeitet.
Kopiere eines der Beispiele unten. Alle sind reines JavaScript ohne Bibliothek.
Übergib eine benannte Funktion, wenn du den Listener später entfernen willst. Eine Inline-Arrow-Function lässt sich später nicht mehr zuordnen.
AbortController entfernt eine ganze Gruppe von Listenern mit einem einzigen abort()-Aufruf, was gut zu Komponenten passt, die gemountet und wieder entfernt werden.
Lausche auf submit am Formular, nicht auf click am Button, damit auch das Drücken von Enter in einem Feld verarbeitet wird.
Verwende event.target.closest("selector") in delegierten Handlern. Ein Klick auf ein Icon innerhalb eines Buttons findet trotzdem den Button.
focus und blur bubbeln nicht. Delegiere stattdessen focusin und focusout.
Häufige Fragen
Was ist Event Delegation?
Statt an jeden Eintrag einen Listener zu hängen, hängst du einen an ein gemeinsames Elternelement. Weil die meisten Events nach oben bubbeln, bekommt das Elternelement Klicks von allen Kindern mit, auch von später hinzugefügten Einträgen, und erkennt über event.target, welcher angeklickt wurde.
Es muss dieselbe Funktionsreferenz und dieselbe capture-Einstellung bekommen, die addEventListener erhalten hat. Zwei Arrow Functions mit identischem Code sind trotzdem verschiedene Funktionen. Definiere den Handler also einmal und übergib beide Male diese Variable.
Was bewirkt passive: true?
Es sagt dem Browser, dass dein Handler preventDefault nicht aufruft. Die Seite kann also sofort scrollen, statt zu warten, bis dein Code fertig ist. Browser verwenden für wheel- und touch-Listener auf window, document und body bereits standardmäßig passive.
Was ist der Unterschied zwischen target und currentTarget?
target ist das innerste Element, an dem das Event ausgelöst wurde, und bleibt gleich, während das Event nach oben bubbelt. currentTarget ist das Element, dessen Listener gerade läuft, und ändert sich auf jeder Ebene.
Löst form.submit() das submit-Event aus?
Nein. Ein Aufruf von form.submit() aus einem Skript überspringt das submit-Event und die Validierung. Rufe form.requestSubmit() auf, wenn deine submit-Listener und die eingebauten Prüfungen laufen sollen.
addEventListener oder onclick?
Die Eigenschaft onclick enthält genau eine Funktion, eine zweite Zuweisung ersetzt also die erste. Mit addEventListener können sich mehrere unabhängige Listener ein Element teilen, und es unterstützt das Options-Objekt. Deshalb ist es die bessere Standardwahl.
Wie ein Event wandert
Ein ausgelöstes Event durchläuft drei Phasen. In der Capture-Phase wandert es vom window hinunter zum Ziel, erreicht das Ziel und bubbelt dann durch jeden Vorfahren wieder nach oben. Listener laufen in der Bubble-Phase, sofern du nicht capture anforderst.
stopPropagation hält die Reise an, sodass Vorfahren das Event nie mitbekommen. Setze es selten ein, denn delegierte Listener und Analytics weiter oben im Baum funktionieren dann unbemerkt nicht mehr.
Scrollen, ohne die Seite zu bremsen
Scroll-Events können pro Frame Bewegung viele Male ausgelöst werden. Halte den Handler winzig, lies Positionen, statt Layout zu schreiben, und bündle visuelle Änderungen in requestAnimationFrame.
Für Aufgaben wie das Einblenden von Elementen, sobald sie sichtbar werden, ist ein IntersectionObserver meist günstiger, als bei jedem Scrollen zu messen. Das Event scrollend, laut MDN seit Dezember 2025 Baseline, wird einmal ausgelöst, wenn die Bewegung stoppt.
Listener aufräumen
Listener auf langlebigen Objekten wie window oder document halten ihren Handler und alles, worauf er verweist, am Leben. Wenn der Teil der Seite, der sie gebraucht hat, verschwindet, entferne sie.
Die Option signal macht das übersichtlich. Erstelle pro Feature einen AbortController, übergib sein signal an jeden Listener und rufe beim Abbau einmal abort() auf.
Die Event-Typen, die du am häufigsten brauchst
Häufige Events und wo du auf sie lauschst
Event
Wird ausgelöst, wenn
Bubbelt?
Ein Zeiger gedrückt und losgelassen wird, oder Enter bzw. Leertaste auf einem Button
Ja
Sich der Wert eines Felds ändert, während der Besucher tippt
Ja
Der Wert eines Felds übernommen wird, zum Beispiel bei blur oder einer Auswahl
Ja
Ein Formular abgesendet wird, ausgelöst am form-Element
Ja
Eine Taste gedrückt wird
Ja
focus / blur
Ein Element den Fokus erhält oder verliert
Nein
focusin / focusout
Wie focus und blur, aber mit Bubbling
Ja
DOMContentLoaded
Das HTML geparst ist und verzögerte Skripte gelaufen sind, lausche auf document
Nicht relevant
Muster zum Kopieren
Klick mit einem benannten Handler, den du entfernen kannst
Erst dadurch, dass die Funktion in einer Variable steht, funktioniert removeEventListener.
Formular absenden ohne Neuladen
preventDefault stoppt die eigene Navigation des Browsers. event.submitter verrät dir, welcher Submit-Button benutzt wurde.
Event Delegation auf einer Liste
Ein Listener auf der Liste verarbeitet jeden Löschen-Button, auch in Zeilen, die nach dem Laden der Seite hinzugekommen sind.
Ein passiver Scroll-Listener, gedrosselt auf ein Update pro Frame
passive: true lässt das Scrollen sofort starten, und requestAnimationFrame beschränkt die Arbeit auf einmal pro Frame.
once und AbortController
Der erste Listener läuft genau einmal. Die anderen werden alle zusammen mit einem einzigen abort()-Aufruf entfernt.
Tastenkürzel, das Eingaben in Feldern ignoriert
Die Prüfung des Ziels verhindert, dass das Kürzel auslöst, während jemand einen Schrägstrich in ein Suchfeld tippt.
Äpfel
Brot
Kaffee
click auf Button: target {target}
(once: jetzt entfernt)
click hat Testbereich erreicht ({phase}-Phase): target {target}, currentTarget {current}
input: Wert ist jetzt "{value}"
change: Wert übernommen
submit am Formular, submitter {submitter}, preventDefault hat das Neuladen verhindert
scroll (passiv, einmal pro Frame): scrollTop {n}
delegierter click auf Liste: Eintrag {item}
Listener pro Eintrag: {item}
Live-Event-Log
Klicke, tippe, sende ab und scrolle im Testbereich. Jeder Listener-Aufruf wird mit Typ, target und currentTarget ins Log geschrieben.