Start · Sprachen · JavaScript · Referenz · new EventTarget()

new EventTarget()

Methode

Der Konstruktor <code>EventTarget()</code> erzeugt ein eigenständiges Objekt, das Event-Listener registrieren und Ereignisse auslösen kann – ganz ohne DOM-Element.

seit JavaScript Baseline: alle modernen Browser (Chrome 64, Firefo Kategorie: webapi

Signatur

new EventTarget()

Beschreibung

Mit new EventTarget() erhältst du ein leichtgewichtiges Objekt mit den drei Methoden addEventListener(), removeEventListener() und dispatchEvent(). Das ist dasselbe Ereignissystem, das auch DOM-Knoten, window, WebSocket oder AbortSignal verwenden. Früher musste man dafür ein DOM-Element „missbrauchen“ oder eine eigene Event-Emitter-Bibliothek schreiben.

Am häufigsten nutzt man EventTarget als Basisklasse: Mit class Store extends EventTarget bekommen eigene Klassen (Stores, Services, Modelle) ein natives, standardkonformes Ereignissystem. In Verbindung mit CustomEvent kannst du Nutzdaten über die Eigenschaft detail übergeben.

Weil es die native API ist, funktionieren alle Listener-Optionen: once, passive, capture und vor allem signal, womit du Listener gesammelt per AbortController entfernen kannst. Das Event wird synchron ausgelöst: dispatchEvent() kehrt erst zurück, wenn alle Listener gelaufen sind.

Rückgabewert

Typ
EventTarget
Beschreibung
Eine neue, leere EventTarget-Instanz ohne registrierte Listener.

Beispiele

Einfaches EventTarget erzeugen und Ereignis auslösen

const bus = new EventTarget();

bus.addEventListener('ping', (event) => {
  console.log(`Empfangen: ${event.type}`);
});

bus.dispatchEvent(new Event('ping'));
Empfangen: ping

Eigene Klasse mit Ereignissen und CustomEvent-Daten

class Warenkorb extends EventTarget {
  #artikel = [];

  hinzufuegen(name, preis) {
    this.#artikel.push({ name, preis });
    this.dispatchEvent(new CustomEvent('change', {
      detail: { anzahl: this.#artikel.length, summe: this.summe }
    }));
  }

  get summe() {
    return this.#artikel.reduce((s, a) => s + a.preis, 0);
  }
}

const korb = new Warenkorb();
korb.addEventListener('change', ({ detail }) => {
  console.log(`${detail.anzahl} Artikel, ${detail.summe.toFixed(2)} €`);
});

korb.hinzufuegen('Buch', 19.9);
korb.hinzufuegen('Stift', 2.5);
1 Artikel, 19.90 € 2 Artikel, 22.40 €

Listener per AbortController und once aufräumen

const status = new EventTarget();
const controller = new AbortController();

status.addEventListener('update', (e) => console.log('Update:', e.detail),
  { signal: controller.signal });
status.addEventListener('ready', () => console.log('Bereit!'), { once: true });

status.dispatchEvent(new CustomEvent('update', { detail: 1 }));
status.dispatchEvent(new Event('ready'));
status.dispatchEvent(new Event('ready')); // wird ignoriert (once)

controller.abort(); // entfernt den update-Listener
status.dispatchEvent(new CustomEvent('update', { detail: 2 })); // keine Ausgabe
Update: 1 Bereit!

// Wichtig · Fallstricke

  • Kein Bubbling: Ein eigenständiges EventTarget hat keine Eltern. bubbles: true und Capture-Phase haben daher keine Wirkung – nur der direkte Empfänger wird benachrichtigt.
  • Synchron: dispatchEvent() ruft alle Listener sofort nacheinander auf. Wirft ein Listener eine Ausnahme, wird sie gemeldet (reportError), die übrigen Listener laufen aber weiter, und dispatchEvent() selbst wirft nicht.
  • Event-Objekte nicht wiederverwenden, solange sie ausgelöst werden: Ein Event, das gerade verarbeitet wird, erneut auszulösen, führt zu einem InvalidStateError.
  • Derselbe Listener (gleiche Funktionsreferenz, gleiches capture) wird nur einmal registriert. Zum Entfernen per removeEventListener() brauchst du die identische Referenz – anonyme Pfeilfunktionen lassen sich so nicht entfernen, hier hilft die Option signal.
  • Kompatibilität: Der Konstruktor ist in älteren Browsern (Safari < 14, IE) nicht verfügbar; Unterklassen per extends brauchen ebenfalls diese Versionen. In Node.js ist EventTarget seit Version 15 global verfügbar (vorher experimentell) und unabhängig vom klassischen EventEmitter.