Signatur
Beschreibung
WindowClient.focus() steht nur im Service Worker zur Verfügung. Die Methode holt ein bereits geöffnetes Fenster oder einen Tab, der vom Service Worker kontrolliert wird, in den Vordergrund und gibt ihm den Benutzereingabefokus. Das zurückgegebene Promise wird mit dem WindowClient erfüllt, dessen Eigenschaften (z. B. focused, visibilityState) den neuen Zustand widerspiegeln.
Der typische Einsatz ist das Ereignis notificationclick: Klickt der Nutzer auf eine Push-Benachrichtigung, sucht man per clients.matchAll() nach einem passenden offenen Tab und fokussiert ihn. Nur wenn es keinen gibt, öffnet man mit clients.openWindow() ein neues Fenster. So vermeidet man doppelte Tabs der eigenen Anwendung.
Wichtig: Der Aufruf ist nur erlaubt, wenn gerade eine Nutzeraktivierung vorliegt. In der Praxis heißt das, dass er innerhalb eines notificationclick-Handlers erfolgen muss, und zwar solange das Ereignis noch aktiv ist. Deshalb gehört der Aufruf in event.waitUntil(). Sonst wird das Promise mit einem InvalidAccessError abgelehnt.
Rückgabewert
WindowClient erfüllt wird. Es wird mit einem InvalidAccessError (DOMException) abgelehnt, wenn keine Nutzeraktivierung vorliegt oder der Fokus aus einem anderen Grund nicht gesetzt werden kann.Beispiele
Vorhandenen Tab beim Klick auf eine Benachrichtigung fokussieren
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const zielUrl = new URL('/nachrichten', self.location.origin).href;
event.waitUntil((async () => {
const fenster = await self.clients.matchAll({
type: 'window',
includeUncontrolled: true
});
// Passenden offenen Tab suchen und fokussieren
for (const client of fenster) {
if (client.url === zielUrl && 'focus' in client) {
return client.focus();
}
}
// Kein passender Tab offen -> neues Fenster öffnen
return self.clients.openWindow(zielUrl);
})());
});
Fokussieren und danach eine Nachricht an den Tab senden
// sw.js
self.addEventListener('notificationclick', (event) => {
event.notification.close();
const { chatId } = event.notification.data ?? {};
event.waitUntil((async () => {
const [client] = await self.clients.matchAll({ type: 'window' });
if (!client) {
return self.clients.openWindow(`/chat/${chatId}`);
}
const fokussiert = await client.focus();
console.log('Fokus:', fokussiert.focused, fokussiert.visibilityState);
// Der Seite mitteilen, welcher Chat geöffnet werden soll
fokussiert.postMessage({ typ: 'chat-oeffnen', chatId });
})());
});
Fehlerbehandlung bei fehlender Nutzeraktivierung
// sw.js – focus() außerhalb von notificationclick schlägt fehl
self.addEventListener('message', (event) => {
event.waitUntil((async () => {
try {
await event.source.focus();
} catch (err) {
console.warn(err.name, '- focus() ist nur nach Nutzerinteraktion erlaubt');
}
})());
});
// Wichtig · Fallstricke
- Nur nach Nutzeraktivierung: Außerhalb eines
notificationclick-Handlers, oder wenn der Aufruf erst nach dessen Ende kommt, wird das Promise mitInvalidAccessErrorabgelehnt. Verpacke den Aufruf immer inevent.waitUntil()und rufe ihn möglichst früh auf. Langeawait-Ketten vorfocus()können das Zeitfenster der Aktivierung überschreiten. - Die Methode gibt es nur auf
WindowClient, nicht auf dem allgemeinenClient. Worker-Clients haben keinfocus(). Filtere deshalb mitclients.matchAll({ type: 'window' })oder prüfe vorher mit'focus' in client. - Standardmäßig liefert
matchAll()nur Clients, die der Service Worker kontrolliert. MitincludeUncontrolled: truefindest du auch Tabs, die noch nicht kontrolliert werden, etwa direkt nach der Installation. - Das Betriebssystem oder der Browser kann den Fokuswechsel einschränken, zum Beispiel wenn das Browserfenster minimiert ist. Das Verhalten unterscheidet sich je nach Plattform.
- Die Methode wird in Chrome, Edge, Firefox und Safari (ab 16) unterstützt. Service Worker brauchen einen sicheren Kontext (HTTPS oder
localhost).