Signatur
Beschreibung
Das Ereignis statechange wird an einer ServiceWorker-Instanz ausgelöst, sobald sich der Wert von ServiceWorker.state ändert. Ein Service Worker durchläuft dabei die Zustände parsed, installing, installed, activating, activated und schließlich eventuell redundant.
Typischerweise nutzt man das Ereignis auf der Seite (nicht im Worker-Skript selbst), um den Lebenszyklus eines neu registrierten oder aktualisierten Workers zu verfolgen. Ein klassischer Anwendungsfall ist der Hinweis „Neue Version verfügbar – neu laden?“: Sobald ein Update-Worker den Zustand installed erreicht und bereits ein navigator.serviceWorker.controller existiert, wartet eine neue Version auf ihre Aktivierung.
Den Handler registriert man entweder mit addEventListener("statechange", handler) oder über die Eigenschaft onstatechange. Das übergebene Objekt ist ein einfaches Event; den neuen Zustand liest man über event.target.state aus. Das Ereignis ist nicht abbrechbar und steigt nicht auf (kein Bubbling).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "statechange". |
|
| $handler Pflicht | (event: Event) => void | Callback, der bei jeder Zustandsänderung aufgerufen wird. event.target ist der betroffene ServiceWorker; der neue Zustand steht in event.target.state. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once oder signal (zum Entfernen per AbortController). |
Beispiele
Lebenszyklus eines neu installierten Workers verfolgen
const registration = await navigator.serviceWorker.register('/sw.js');
const worker = registration.installing ?? registration.waiting ?? registration.active;
if (worker) {
console.log('Startzustand:', worker.state);
worker.addEventListener('statechange', (event) => {
console.log('Neuer Zustand:', event.target.state);
});
}
Hinweis „Update verfügbar“ anzeigen
const registration = await navigator.serviceWorker.register('/sw.js');
registration.addEventListener('updatefound', () => {
const newWorker = registration.installing;
if (!newWorker) return;
newWorker.addEventListener('statechange', () => {
// installed + vorhandener Controller = neue Version wartet
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
const banner = document.querySelector('#update-banner');
banner.hidden = false;
banner.querySelector('button').addEventListener('click', () => {
newWorker.postMessage({ type: 'SKIP_WAITING' });
}, { once: true });
}
});
});
// Nach Übernahme durch den neuen Worker neu laden
navigator.serviceWorker.addEventListener('controllerchange', () => location.reload());
Über onstatechange und Handler wieder entfernen
const registration = await navigator.serviceWorker.register('/sw.js');
const worker = registration.installing;
if (worker) {
// Variante 1: on-Property
worker.onstatechange = () => {
if (worker.state === 'activated') {
console.log('Worker aktiv – Offline-Modus bereit');
worker.onstatechange = null; // Handler entfernen
}
};
// Variante 2: addEventListener + removeEventListener
const onRedundant = () => {
if (worker.state === 'redundant') {
console.warn('Installation fehlgeschlagen oder ersetzt');
worker.removeEventListener('statechange', onRedundant);
}
};
worker.addEventListener('statechange', onRedundant);
}
// Wichtig · Fallstricke
- Nur Änderungen: Für den Zustand, den der Worker bei der Registrierung des Handlers schon hat, wird kein Ereignis ausgelöst. Prüfe daher immer zuerst
worker.statedirekt. - Zustände können übersprungen werden: Schlägt die Installation fehl, wechselt der Worker direkt zu
redundant. Verlasse dich nicht darauf, jeden Zwischenzustand mitzubekommen. - Richtiges Objekt wählen:
statechangewird amServiceWorkerausgelöst, nicht an derServiceWorkerRegistrationund nicht annavigator.serviceWorker. Für neue Versionen erst aufupdatefoundhören und dann den Handler anregistration.installinghängen. - Kein Ersatz für Worker-Ereignisse: Im Worker-Skript selbst verwendet man
installundactivatestattstatechange. - Kompatibilität: Wird in allen modernen Browsern unterstützt. Service Worker laufen nur in sicheren Kontexten (HTTPS oder
localhost) und sind im privaten Modus mancher Browser (z. B. ältere Firefox-Versionen) nicht verfügbar. Prüfe vorab mit'serviceWorker' in navigator.