Signatur
Beschreibung
Die Eigenschaft visibilityState eines WindowClient-Objekts liefert im Service Worker den Sichtbarkeitszustand des zugehörigen Dokuments (Tab oder Fenster). Der Wert entspricht dem, was document.visibilityState im Dokument selbst zurückgeben würde, allerdings als Momentaufnahme zum Zeitpunkt, an dem das WindowClient-Objekt erzeugt wurde.
Typischer Einsatz ist die Entscheidung in einem push- oder notificationclick-Handler, ob eine Benachrichtigung angezeigt werden muss oder ob der Nutzer die App bereits vor Augen hat. Ebenso lässt sich damit bevorzugt ein sichtbarer Tab auswählen, an den eine Nachricht per postMessage() geschickt oder der per focus() in den Vordergrund geholt wird.
Mögliche Werte sind:
"visible"– der Inhalt ist zumindest teilweise sichtbar (Vordergrund-Tab eines nicht minimierten Fensters)."hidden"– der Inhalt ist nicht sichtbar (Hintergrund-Tab, minimiertes Fenster, gesperrter Bildschirm).
Die Eigenschaft hat keine Parameter; sie wird nur gelesen. WindowClient-Objekte erhält man über clients.matchAll({ type: "window" }), clients.get() oder clients.openWindow().
Rückgabewert
"prerender" ist aus der Spezifikation entfernt worden.Beispiele
Push-Benachrichtigung nur anzeigen, wenn kein Tab sichtbar ist
// service-worker.js
self.addEventListener('push', (event) => {
const data = event.data?.json() ?? { title: 'Neue Nachricht', body: '' };
event.waitUntil((async () => {
const windows = await clients.matchAll({ type: 'window', includeUncontrolled: true });
const sichtbar = windows.some((client) => client.visibilityState === 'visible');
if (sichtbar) {
// App ist offen und sichtbar: Daten direkt an die Seite schicken
windows.forEach((client) => client.postMessage({ type: 'push', payload: data }));
return;
}
await self.registration.showNotification(data.title, { body: data.body });
})());
});
Beim Klick auf eine Benachrichtigung den sichtbaren Tab bevorzugen
self.addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil((async () => {
const windows = await clients.matchAll({ type: 'window' });
// Sichtbare Tabs zuerst, danach fokussierte
const ziel = windows.find((c) => c.visibilityState === 'visible')
?? windows.find((c) => c.focused)
?? windows[0];
if (ziel) {
await ziel.focus();
await ziel.navigate('/inbox');
} else {
await clients.openWindow('/inbox');
}
})());
});
Sichtbarkeitszustand aller Fenster protokollieren
self.addEventListener('message', async (event) => {
if (event.data !== 'status') return;
const windows = await clients.matchAll({ type: 'window' });
for (const c of windows) {
console.log(c.url, c.visibilityState, c.focused);
}
});
// Wichtig · Fallstricke
- Momentaufnahme: Der Wert wird beim Erzeugen des
WindowClient-Objekts festgehalten und aktualisiert sich nicht. Für einen aktuellen Stand erneutclients.matchAll()oderclients.get(id)aufrufen. - Nur im Service-Worker-Kontext verfügbar. Im Dokument selbst verwendet man
document.visibilityStateund das Ereignisvisibilitychange. "visible"bedeutet nicht zwingend, dass das Fenster den Fokus hat – dafür gibt esWindowClient.focused. Ein Fenster kann sichtbar, aber nicht fokussiert sein (z. B. auf einem zweiten Bildschirm).- Ohne
includeUncontrolled: trueliefertmatchAll()nur Clients, die der Service Worker gerade kontrolliert – offene Tabs können sonst fehlen. - Kompatibilität: Chrome, Edge, Firefox und Safari (ab 16) unterstützen die Eigenschaft. Service Worker setzen einen sicheren Kontext (HTTPS oder
localhost) voraus.