Signatur
Beschreibung
Der Konstruktor CustomEvent() erzeugt ein eigenes, anwendungsspezifisches Ereignis. Anders als ein einfaches Event kann ein CustomEvent über die Option detail beliebige Daten transportieren, zum Beispiel Objekte, Arrays oder primitive Werte. Diese Daten stehen im Listener schreibgeschützt unter event.detail bereit.
Typische Einsatzgebiete sind die lose Kopplung von Komponenten: Web Components melden Zustandsänderungen an ihre Umgebung, Module kommunizieren über einen gemeinsamen EventTarget, oder ein Formular-Widget signalisiert „Auswahl geändert“, ohne dass der Empfänger dessen Interna kennen muss.
Das erzeugte Ereignis wird erst durch target.dispatchEvent(event) tatsächlich ausgelöst. Standardmäßig ist es nicht bubbelnd und nicht abbrechbar; beides muss über bubbles: true bzw. cancelable: true explizit aktiviert werden. Soll das Ereignis die Grenze eines Shadow DOM überwinden, ist zusätzlich composed: true nötig.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, z. B. "warenkorb:hinzugefuegt". Groß-/Kleinschreibung wird unterschieden. |
|
| $options | Object | {} | Optionales Konfigurationsobjekt (erbt die Optionen von EventInit). |
| $options.detail | any | null | Beliebige Nutzdaten, die im Listener über event.detail abrufbar sind. |
| $options.bubbles | boolean | false | Ob das Ereignis im DOM-Baum nach oben aufsteigt. |
| $options.cancelable | boolean | false | Ob event.preventDefault() wirksam ist; dispatchEvent() liefert dann ggf. false. |
| $options.composed | boolean | false | Ob das Ereignis die Shadow-DOM-Grenze in das umgebende Dokument überschreitet. |
Rückgabewert
CustomEvent-Objekt, das noch nicht ausgelöst wurde (isTrusted ist false).Beispiele
Einfaches Ereignis mit Nutzdaten auslösen
const button = document.createElement('button');
button.addEventListener('produkt:gewaehlt', (event) => {
console.log(`Gewählt: ${event.detail.name} (${event.detail.preis} €)`);
});
const ereignis = new CustomEvent('produkt:gewaehlt', {
detail: { name: 'Tastatur', preis: 49.9 }
});
button.dispatchEvent(ereignis);
Bubbelndes Ereignis per Event-Delegation abfangen
const liste = document.createElement('ul');
const eintrag = document.createElement('li');
liste.append(eintrag);
document.body.append(liste);
// Listener nur am Elternelement
liste.addEventListener('eintrag:erledigt', (event) => {
console.log('Erledigt:', event.detail.id, '| Ziel:', event.target.tagName);
});
eintrag.dispatchEvent(new CustomEvent('eintrag:erledigt', {
bubbles: true,
detail: { id: 42 }
}));
Abbrechbares Ereignis: Empfänger kann eine Aktion verhindern
const editor = document.createElement('div');
editor.addEventListener('dokument:schliessen', (event) => {
if (event.detail.ungespeichert) {
event.preventDefault(); // Schließen verhindern
}
});
const darfSchliessen = editor.dispatchEvent(new CustomEvent('dokument:schliessen', {
cancelable: true,
detail: { ungespeichert: true }
}));
console.log(darfSchliessen ? 'Wird geschlossen' : 'Schließen abgebrochen');
Web Component meldet Änderung über Shadow-DOM-Grenze hinweg
class ZaehlerKnopf extends HTMLElement {
#wert = 0;
connectedCallback() {
const root = this.attachShadow({ mode: 'open' });
const btn = document.createElement('button');
btn.textContent = '+1';
btn.addEventListener('click', () => {
this.#wert++;
btn.dispatchEvent(new CustomEvent('zaehler-geaendert', {
detail: { wert: this.#wert },
bubbles: true,
composed: true // verlässt den Shadow DOM
}));
});
root.append(btn);
}
}
customElements.define('zaehler-knopf', ZaehlerKnopf);
document.addEventListener('zaehler-geaendert', (e) => {
console.log('Neuer Wert:', e.detail.wert);
});
document.body.append(document.createElement('zaehler-knopf'));
// Wichtig · Fallstricke
- Standardwerte beachten:
bubbles,cancelableundcomposedsind standardmäßigfalse. Ein häufiger Fehler ist ein Listener am Elternelement, der nie ausgelöst wird, weilbubbles: truefehlt. detailist nur flach schreibgeschützt: Die Eigenschaft selbst lässt sich nicht neu zuweisen, ein übergebenes Objekt kann aber von jedem Listener verändert werden. Bei Bedarf eine Kopie oderObject.freeze()verwenden.- Synchrone Ausführung:
dispatchEvent()ruft alle Listener synchron auf, bevor die Funktion zurückkehrt. Ausnahmen in Listenern werden gemeldet, brechen aber den Aufrufer nicht ab. - Keine vertrauenswürdigen Ereignisse: Selbst erzeugte Ereignisse haben
isTrusted === falseund lösen keine Standardaktionen des Browsers aus (z. B. öffnet ein künstlichesclickkeine Pop-ups). - Benennung: Kollisionen mit nativen Ereignisnamen vermeiden; Präfixe wie
app:oder Bindestriche sind üblich. - Kompatibilität: In allen modernen Browsern verfügbar. Der Internet Explorer unterstützt den Konstruktor nicht; dort war das veraltete
document.createEvent('CustomEvent')mitinitCustomEvent()nötig. In Node.js istCustomEventab Version 19 global verfügbar (ab 18.7 experimentell).