Start · Sprachen · JavaScript · Referenz · IdleDetector

IdleDetector

Schnittstelle

Erkennt, ob der Benutzer am Gerät inaktiv ist (<code>userState</code>) und ob der Bildschirm gesperrt ist (<code>screenState</code>), und meldet Änderungen per <code>change</code>-Ereignis.

seit JavaScript Chromium 94+ (Chrome, Edge, Opera); nicht in Firef Kategorie: webapi

Signatur

interface IdleDetector extends EventTarget

Beschreibung

Das Interface IdleDetector gehört zur Idle Detection API. Es meldet, ob der Benutzer mit dem Gerät arbeitet. Gemeint ist das ganze System, nicht nur das aktuelle Tab: Tastatur, Maus, Touch und Bildschirmschoner zählen mit. Außerdem erfährt man, ob der Bildschirm gesperrt ist. Anders als visibilitychange oder eigene Timer auf Maus-Ereignisse funktioniert die Erkennung auch dann, wenn der Benutzer in einem anderen Programm arbeitet.

Typische Einsatzfälle sind Chat- und Kollaborationsanwendungen, die den Status „abwesend“ anzeigen. Weitere sind Kiosk-Systeme, die sich nach Inaktivität zurücksetzen, und Anwendungen, die aufwendige Berechnungen oder Benachrichtigungen verschieben, solange niemand am Gerät ist.

So läuft die Nutzung ab:

  • Mit IdleDetector.requestPermission() die Berechtigung "idle-detection" anfordern. Das geht nur nach einer Benutzeraktion, zum Beispiel einem Klick.
  • Mit new IdleDetector() eine Instanz erzeugen.
  • Einen Handler für das Ereignis change registrieren, entweder mit addEventListener("change", …) oder über onchange.
  • Mit start({ threshold, signal }) die Überwachung starten.

Mitglieder im Überblick:

  • userState (nur lesbar): "active", "idle" oder null, solange nicht gestartet wurde.
  • screenState (nur lesbar): "locked", "unlocked" oder null.
  • start(options): gibt ein Promise<void> zurück und startet die Überwachung.
  • IdleDetector.requestPermission() (statisch): gibt ein Promise<"granted"|"denied"> zurück.
  • Ereignis change: wird ausgelöst, sobald sich userState oder screenState ändert.

Eine eigene stop()-Methode gibt es nicht. Die Überwachung wird beendet, indem man das AbortSignal abbricht, das an start() übergeben wurde.

Parameter

Name Typ Default Beschreibung
$options object {} Optionen für start(options). Der Konstruktor new IdleDetector() selbst nimmt keine Argumente.
$options.threshold number 60000 Zeit ohne Aktivität in Millisekunden, nach der der Benutzer als "idle" gilt. Der Mindestwert ist 60000 (1 Minute). Kleinere Werte führen zu einem TypeError.
$options.signal AbortSignal Signal eines AbortController. Mit abort() wird die Überwachung beendet.

Rückgabewert

Typ
IdleDetector
Beschreibung
new IdleDetector() liefert eine neue Instanz. start() gibt ein Promise<void> zurück, das erfüllt wird, sobald die Überwachung läuft. requestPermission() gibt ein Promise<string> mit "granted" oder "denied" zurück.

Beispiele

Berechtigung anfordern und Überwachung starten

const button = document.querySelector('#idle-start');

button.addEventListener('click', async () => {
  if (!('IdleDetector' in window)) {
    console.log('Idle Detection API wird nicht unterstützt.');
    return;
  }

  // Muss durch eine Benutzeraktion ausgelöst werden
  const state = await IdleDetector.requestPermission();
  if (state !== 'granted') {
    console.log('Berechtigung verweigert.');
    return;
  }

  const detector = new IdleDetector();
  detector.addEventListener('change', () => {
    console.log(`Benutzer: ${detector.userState}, Bildschirm: ${detector.screenState}`);
  });

  await detector.start({ threshold: 60_000 });
  console.log('Überwachung gestartet.');
});
Überwachung gestartet. Benutzer: idle, Bildschirm: unlocked Benutzer: idle, Bildschirm: locked

Überwachung per AbortController beenden

const controller = new AbortController();

const startIdleWatch = async () => {
  const detector = new IdleDetector();
  detector.onchange = () => console.log('Status:', detector.userState);

  try {
    await detector.start({ threshold: 120_000, signal: controller.signal });
  } catch (err) {
    // z. B. NotAllowedError ohne Berechtigung
    console.error(err.name, err.message);
  }
};

startIdleWatch();

// Später, etwa beim Abmelden:
document.querySelector('#logout').addEventListener('click', () => {
  controller.abort();
  console.log('Idle-Überwachung beendet.');
});
Idle-Überwachung beendet.

Chat-Status automatisch auf „abwesend“ setzen

const setPresence = async (status) => {
  await fetch('/api/presence', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ status })
  });
};

const watchPresence = async () => {
  const { state } = await navigator.permissions.query({ name: 'idle-detection' });
  if (state !== 'granted') return; // Berechtigung noch nicht erteilt

  const detector = new IdleDetector();
  detector.addEventListener('change', () => {
    const away = detector.userState === 'idle' || detector.screenState === 'locked';
    setPresence(away ? 'away' : 'online');
  });
  await detector.start({ threshold: 5 * 60_000 });
};

watchPresence();

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die API gibt es nur in Chromium-basierten Browsern (ab Chrome/Edge 94). Mozilla und Apple lehnen sie aus Datenschutzgründen ab. Deshalb immer mit 'IdleDetector' in window prüfen, ob die API vorhanden ist, und einen Ersatzweg vorsehen, zum Beispiel über visibilitychange.
  • Sicherer Kontext und Berechtigung: Die API funktioniert nur über HTTPS. requestPermission() muss durch eine Benutzeraktion ausgelöst werden, sonst wird das Promise mit NotAllowedError abgelehnt. Ohne erteilte Berechtigung schlägt auch start() fehl.
  • Permissions Policy: In iframes muss das einbettende Dokument die Nutzung erlauben: allow="idle-detection".
  • Mindestschwelle: threshold muss mindestens 60000 ms betragen. Die Einschränkung soll verhindern, dass Benutzeraktivität sekundengenau mitverfolgt werden kann.
  • Datenschutz: Die API verrät, ob jemand gerade am Gerät sitzt. Sie sollte deshalb nur mit einem klar erkennbaren Nutzen eingesetzt werden, und die Benutzer sollten darüber informiert werden.
  • Instanzen: Eine Instanz kann nur einmal gestartet werden. Wurde sie abgebrochen, legt man für einen Neustart eine neue Instanz an.
  • userState und screenState haben den Wert null, bis start() erfolgreich abgeschlossen ist.