Start · Sprachen · JavaScript · Referenz · WindowClient.focused

WindowClient.focused

Eigenschaft

Schreibgeschützter boolescher Wert, der angibt, ob das durch den <code>WindowClient</code> repräsentierte Fenster bzw. der Tab aktuell den Fokus hat.

seit JavaScript Baseline: alle modernen Browser (Service Worker) Kategorie: webapi

Signatur

WindowClient.focused

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

Typ
boolean
Beschreibung
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}`);
  });
});
https://example.com/ | fokussiert: true | sichtbar: visible https://example.com/settings | fokussiert: false | sichtbar: hidden

// Wichtig · Fallstricke

  • Nur im Service-Worker-Kontext verfügbar: WindowClient-Objekte bekommt man über clients.matchAll({ type: 'window' }), clients.get(), clients.openWindow() oder als event.source einer Nachricht. Auf der normalen Seite verwendet man stattdessen document.hasFocus().
  • Momentaufnahme: Der Wert wird nicht live aktualisiert. Vor Entscheidungen immer frisch mit clients.matchAll() abfragen.
  • Ohne type: 'window' liefert matchAll() standardmäßig ebenfalls nur Fenster-Clients, bei type: 'all' können aber auch Worker-Clients ohne focused enthalten sein, dann ist die Eigenschaft undefined.
  • focused und visibilityState sind 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.