Nachdem wir uns im Artikel „JavaScript Basis: addEventListener Richtig Verwenden!“ mit der Basis von Event Listenern beschäftigt haben. Will ich dir nun erklären, wie du eigene Custom Events auslösen kannst, sodass du Event Listener für eigene Events registrieren kannst. Zum Beispiel, um Notifications in deiner Webseite auszugeben. Angenommen, du hast in deiner Webseite einen Listener auf dem Document, mit dem du Notifications ausgeben kannst. Und in deinen Erweiterungen, Plugins oder Widgets – wie auch immer man es gerade nennen möchte – kannst du ein Event auslösen, das eine Nachricht sendet, deine Listener kann darauf dann hören.
Custom Events können in jedem modernen Browser verwendet werden. Bei einem CustomEvent
können zusätzliche Informationen über die Eigenschaft detail
in den Optionen mitgegeben werden.
Gerade also für die Kommunikation zwischen verschiedenen Teilen einer Anwendung oder auch bei Web Components eignen sich CustomEvents
für den Austausch.
Wir beginnen mit der Klasse new CustomEvent
, mit dieser kannst du ein Event erzeugen, dass du anschließende auslösen kannst. Alternative dazu können synthetische Events auch über new Event
erzeugt werden. (Jedes Event, das durch JavaScript und nicht vom Browser selbst ausgelöst wird, ist ein synthetisches Event). Der Unterschied in dem Erzeugen liegt hier bei dem Wert detail
mit diesem kann ein beliebiger Wert zugeordnet werden sei es ein string
oder ein Object
alles ist hier möglich. So können zusätzliche Informationen übermittelt werden.
Als erster Parameter wird immer eine String angegeben. Es sollte hier das Schreiben von camelCase vermieden werden, da diese zu Komplikationen führen könnte. Weshalb kebab-case der Standard für Custom Events in Vanilla JS ist. Zusätzlich wird gerne mit einem Doppelpunkt zwischen Paketname und Event Typ differenziert.
Für ein Paket für das Senden von Nachrichten in den HTML DOM. Könnte der Name sich nun folgendermaßen erschließen: notifications:send
.
new CustomEvent(eventName: string,options: Object)
Key | Default | Beschreibung |
---|---|---|
bubbles | false | Um das Bubbeling von Events zu Aktivieren. |
cancelable | false | Mit der Option cancelable kann die Verwendung von preventDefault genutzt werden. Heißt, wenn preventDefault verwendet wird. Gibt die Methode dispatchEvent ein False zurück anstatt von True. |
composed | false | Wenn der Wert True ist, wird das Event auch aus einem shadowDom heraus gereicht und kann dort weiter verwendet werden. Für interaktive Web Components unter anderem interessant. |
Um ein Custom Event mit diesem Wissen aufzubauen, reicht folgender Code. Häufig ergibt es Sinn, diese Methodik in eine eigene Funktion auszulagern, da die Detailwerte häufig dynamisch sein sollen.
let customEvent = new CustomEvent('notification:send-message',{
bubbles: true,
cancelable: false,
detail: {
message: 'Hallo Welt',
timeout: 60
}
});
Nachdem wir eine Beispielevent angelegt haben, wird es noch nicht ausgelöst, um Custom Events auszulösen, benötigten wir die Methode dispatchEvent
diese Erwartet ein Event
Typ. Um unsere Nachricht nun als Event auslösen, müssen wir noch definieren, anhand welchen Element wir diese auslösen möchten. Wir können etwa es auslösen in dem wir sagen das Document hat dieses Event und kann jetzt das vorher erzeugte Custom Event nutzen.
document.dispatchEvent(customEvent)
Vor dem Auslösen sollte natürlich schon der EventListener angelegt sein. Diese ist ziemlich simple als Typ geben wir jetzt den zuvor definierten String an. Später in deiner Anwendung ist es sinnvoll die Funktion auszulagern, so, dass du nur den Funktionsnamen übergibst um den EventListener auch wieder entfernen zu können. Die Variable Event enthält jetzt ein CustomEvent Objekt mit dem Property detail in dem wir unsere zwei zuvor definierten Werte auch wieder zur Verfügung haben.
document.addEventListener('notification:send-message', (event) => {
console.log(event.detail.message)
console.log(event.detail.timeout)
})
Als kleines und simples Beispiel habe ich einmal zwei Components vorbereitet, einen Sender und einen Empfänger. Der Empfänger hört allen Sendern zu, heißt er kann jetzt die Eingaben von allen Sendern verarbeiteten, das können natürlich auch unterschiedliche Komponenten in einer echten Anwendung sein.
Der Sender löst bei jedem Keyup das Event zum Senden des aktuellen Values des Textfeldes aus.
"use strict";
class notificationSender extends HTMLElement {
constructor() {
super();
this._input = document.createElement('input');
this.sendMessage = this.sendMessage.bind(this);
}
connectedCallback() {
this.appendChild(this._input);
this._input.addEventListener('keyup', this.sendMessage);
}
sendMessage(e) {
var _a;
let value = (_a = e.target) === null || _a === void 0 ? void 0 : _a.value;
if (value) {
this.dispatchEvent(this.getCustomEvent(value));
}
}
getCustomEvent(message) {
return new CustomEvent('notification:send-message', {
bubbles: true,
cancelable: false,
detail: {
message: message
}
});
}
}
customElements.define('notification-sender', notificationSender);
Der Empfänger hört allen Sendern zu, theoretisch könnte er auch nur dem document
zuhören, da wir dem Event das Bubblen erlaubt haben. In der Methode Handle Event kannst du nun beliebige mit der Textnachricht fortfahren.
"use strict";
class notificationReciver extends HTMLElement {
constructor() {
super();
this.handleEvent = this.handleEvent.bind(this);
}
connectedCallback() {
let senders = document.querySelectorAll('notification-sender');
senders.forEach(sender => {
sender.addEventListener('notification:send-message', this.handleEvent);
});
}
handleEvent(e) {
console.log(e.detail.message);
}
}
customElements.define('notification-reciver', notificationReciver);
Der Vorteil von CustomEvents in diesem Szenario gegenüber einer Funktion, der du die Nachricht übergibst und dann an deiner entsprechenden Stelle ausgibst, liegt dort drinnen: Es ist nicht notwendig zu wissen, wie der EventListener implementiert wurde, oder ob du Zugriff auf eine Funktion aus einem anderen Scope hast. Deine Scripte können unabhängiger voneinander laufen. Grade im Bereich von Web Components hat sich dieser Weg der Kommunikation bewährt, um andere Components auf dem Laufenden zu halten, ohne genau zu wissen, wer diese Informationen jetzt gerade haben möchte. Grade bei Childcomponents, die ihren Parentcomponents etwas mitteilen wollen, eignet sich diese Methode.
Hinterlasse mir gerne einen Kommentar zum Artikel und wie er dir weitergeholfen hat beziehungsweise, was dir helfen würde das Thema besser zu verstehen. Oder hast du einen Fehler entdeckt, den ich korrigieren sollte? Schreibe mir auch dazu gerne ein Feedback!
Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "JavaScript, eigene Events definieren - CustomEvent"!