Signatur
Beschreibung
Die Eigenschaft focused gehört zum Interface WindowClient, das in einem Service Worker ein vom Worker kontrolliertes Fenster (Tab, Top-Level-Dokument oder iframe) darstellt. Sie liefert true, wenn dieses Fenster gerade den Eingabefokus hat, sonst false.
Typischer Anwendungsfall ist die Behandlung von Push-Nachrichten und Benachrichtigungen: Hat der Nutzer die Anwendung bereits im Vordergrund geöffnet, kann man auf eine Systembenachrichtigung verzichten und die Daten stattdessen per postMessage() direkt an die Seite schicken. Bei einem notificationclick lässt sich so ermitteln, ob ein vorhandener Tab erst mit WindowClient.focus() in den Vordergrund geholt werden muss.
Wichtig: Der Wert ist eine Momentaufnahme zum Zeitpunkt, an dem das WindowClient-Objekt erzeugt wurde (z. B. durch clients.matchAll()). Ändert sich der Fokus danach, wird das bestehende Objekt nicht aktualisiert — für einen aktuellen Stand muss man clients.matchAll() erneut aufrufen.
Rückgabewert
true, wenn der Client zum Erzeugungszeitpunkt des Objekts den Fokus hatte, andernfalls false.Beispiele
Push nur anzeigen, wenn kein Fenster fokussiert ist
// sw.js
self.addEventListener('push', (event) => {
const data = event.data?.json() ?? { title: 'Neuigkeit', body: '' };
event.waitUntil((async () => {
const windows = await self.clients.matchAll({
type: 'window',
includeUncontrolled: true
});
const focusedClient = windows.find((client) => client.focused);
if (focusedClient) {
// App ist im Vordergrund: Daten direkt an die Seite senden
focusedClient.postMessage({ type: 'push', payload: data });
return;
}
await self.registration.showNotification(data.title, { body: data.body });
})());
});
Beim Klick auf eine Benachrichtigung vorhandenen Tab fokussieren
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const targetUrl = new URL('/inbox', self.location.origin).href;
event.waitUntil((async () => {
const windows = await self.clients.matchAll({ type: 'window' });
const existing = windows.find((c) => c.url === targetUrl);
if (existing) {
if (!existing.focused) {
await existing.focus();
}
return;
}
await self.clients.openWindow(targetUrl);
})());
});
Fokus-Status aller Fenster protokollieren
// sw.js — z. B. in einem message-Handler
self.addEventListener('message', async (event) => {
if (event.data !== 'status') return;
const windows = await self.clients.matchAll({ type: 'window' });
windows.forEach((c) => {
console.log(`${c.url} | fokussiert: ${c.focused} | sichtbar: ${c.visibilityState}`);
});
});
// Wichtig · Fallstricke
- Nur im Service-Worker-Kontext verfügbar:
WindowClient-Objekte bekommt man überclients.matchAll({ type: 'window' }),clients.get(),clients.openWindow()oder alsevent.sourceeiner Nachricht. Auf der normalen Seite verwendet man stattdessendocument.hasFocus(). - Momentaufnahme: Der Wert wird nicht live aktualisiert. Vor Entscheidungen immer frisch mit
clients.matchAll()abfragen. - Ohne
type: 'window'liefertmatchAll()standardmäßig ebenfalls nur Fenster-Clients, beitype: 'all'können aber auch Worker-Clients ohnefocusedenthalten sein, dann ist die Eigenschaftundefined. focusedundvisibilityStatesind nicht dasselbe: Ein Tab kann sichtbar sein ('visible'), obwohl ein anderes Fenster oder eine andere Anwendung den Fokus hat.- Service Worker erfordern einen sicheren Kontext (HTTPS oder
localhost). Die Eigenschaft wird von allen aktuellen Browsern unterstützt.