Signatur
Beschreibung
Das Interface NotificationEvent gehört zur Notifications API und beschreibt Ereignisse, die ein Service Worker empfängt, wenn der Nutzer mit einer von ihm angezeigten Benachrichtigung interagiert. Solche Benachrichtigungen werden meist mit ServiceWorkerRegistration.showNotification() erzeugt, oft als Reaktion auf ein push-Ereignis. Ausgelöst werden vor allem die Ereignisse notificationclick (Klick auf die Benachrichtigung oder einen Aktions-Button) und notificationclose (Benachrichtigung wurde vom Nutzer geschlossen).
Da NotificationEvent von ExtendableEvent erbt, steht die Methode event.waitUntil(promise) zur Verfügung. Mit ihr hält man den Service Worker am Leben, bis asynchrone Arbeit wie clients.openWindow(), das Fokussieren eines offenen Tabs oder ein Analytics-Aufruf per fetch() erledigt ist.
Wichtige Eigenschaften (nur lesbar):
notification– dasNotification-Objekt, das das Ereignis ausgelöst hat (inklusivedata,tag,titleusw.).action– dieaction-ID des angeklickten Aktions-Buttons; leerer String, wenn die Benachrichtigung selbst angeklickt wurde.reply– (nicht standardisiert, kaum unterstützt) Texteingabe bei Inline-Antworten.
Den Konstruktor new NotificationEvent(type, init) braucht man im Anwendungscode praktisch nie – der Browser erzeugt die Ereignisse selbst. Er ist vor allem für Tests und Polyfills nützlich und nur innerhalb eines Service Workers verfügbar.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, z. B. "notificationclick" oder "notificationclose" (nur beim Konstruktor). |
|
| $init Pflicht | object | Initialisierungsobjekt: notification (Notification, Pflicht), action (string, Standard "") sowie die Optionen von ExtendableEventInit (bubbles, cancelable, composed). |
Rückgabewert
NotificationEvent-Objekt (beim Konstruktor-Aufruf). In der Praxis erhält man es als Argument des Event-Handlers.Beispiele
Klick auf Benachrichtigung: vorhandenen Tab fokussieren oder neu öffnen
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const url = event.notification.data?.url ?? '/';
event.waitUntil((async () => {
const allClients = await clients.matchAll({ type: 'window', includeUncontrolled: true });
const existing = allClients.find((c) => new URL(c.url).pathname === url);
if (existing) {
return existing.focus();
}
return clients.openWindow(url);
})());
});
Aktions-Buttons unterscheiden mit event.action
// Anzeige, z. B. im push-Handler
self.addEventListener('push', (event) => {
event.waitUntil(
self.registration.showNotification('Neue Nachricht', {
body: 'Anna: Treffen wir uns um 15 Uhr?',
tag: 'chat-42',
data: { chatId: 42 },
actions: [
{ action: 'open', title: 'Öffnen' },
{ action: 'mute', title: 'Stummschalten' }
]
})
);
});
self.addEventListener('notificationclick', (event) => {
const { chatId } = event.notification.data;
event.notification.close();
if (event.action === 'mute') {
event.waitUntil(fetch(`/api/chats/${chatId}/mute`, { method: 'POST' }));
} else {
// '' (Klick auf die Benachrichtigung) oder 'open'
event.waitUntil(clients.openWindow(`/chat/${chatId}`));
}
});
Schließen protokollieren mit notificationclose (on-Property)
// sw.js
self.onnotificationclose = (event) => {
const { tag } = event.notification;
console.log('Benachrichtigung verworfen:', tag);
event.waitUntil(
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: 'dismissed', tag })
})
);
};
Ereignis manuell erzeugen (z. B. für Tests im Service Worker)
// sw.js – nur zu Testzwecken
self.addEventListener('message', async (msg) => {
if (msg.data !== 'test-click') return;
await self.registration.showNotification('Test', { tag: 'test' });
const [notification] = await self.registration.getNotifications({ tag: 'test' });
const evt = new NotificationEvent('notificationclick', { notification, action: '' });
console.log(evt.type, evt.notification.title, JSON.stringify(evt.action));
});
// Wichtig · Fallstricke
- Nur im Service Worker:
NotificationEventexistiert ausschließlich imServiceWorkerGlobalScope. Benachrichtigungen, die pernew Notification()im Fenster erzeugt wurden, lösen stattdessenclick/closeauf demNotification-Objekt selbst aus. - Benachrichtigung schließen: Ein Klick schließt die Benachrichtigung auf vielen Plattformen nicht automatisch – rufe
event.notification.close()selbst auf. clients.openWindow()undclient.focus()sind nur während der Verarbeitung vonnotificationclickerlaubt (Nutzeraktivierung). Rufe sie synchron im Handler bzw. innerhalb vonwaitUntil()auf, nicht nach langen Verzögerungen – sonst werden sie abgelehnt.waitUntil()nicht vergessen: Ohne sie kann der Browser den Service Worker beenden, bevor asynchrone Arbeit abgeschlossen ist.notificationclosewird nicht zuverlässig auf allen Plattformen gefeuert (z. B. beim Löschen aller Benachrichtigungen, oder wenn per Codeclose()aufgerufen wird). Nicht für kritische Logik verwenden.- Kompatibilität: Aktions-Buttons (
actions) werden von Safari und Firefox auf dem Desktop nur eingeschränkt bzw. gar nicht unterstützt;replyist nicht standardisiert. Auf iOS funktionieren Web-Push-Benachrichtigungen nur für zum Home-Bildschirm hinzugefügte Web-Apps (ab iOS 16.4). - Sicherheit: Daten in
notification.datastammen oft aus Push-Nachrichten – URLs voropenWindow()validieren (z. B. nur eigene Origin erlauben), um Open-Redirect-Missbrauch zu verhindern.