Signatur
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
changeregistrieren, entweder mitaddEventListener("change", …)oder überonchange. - Mit
start({ threshold, signal })die Überwachung starten.
Mitglieder im Überblick:
userState(nur lesbar):"active","idle"odernull, solange nicht gestartet wurde.screenState(nur lesbar):"locked","unlocked"odernull.start(options): gibt einPromise<void>zurück und startet die Überwachung.IdleDetector.requestPermission()(statisch): gibt einPromise<"granted"|"denied">zurück.- Ereignis
change: wird ausgelöst, sobald sichuserStateoderscreenStateä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
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 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.');
});
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 windowprüfen, ob die API vorhanden ist, und einen Ersatzweg vorsehen, zum Beispiel übervisibilitychange. - Sicherer Kontext und Berechtigung: Die API funktioniert nur über HTTPS.
requestPermission()muss durch eine Benutzeraktion ausgelöst werden, sonst wird das Promise mitNotAllowedErrorabgelehnt. Ohne erteilte Berechtigung schlägt auchstart()fehl. - Permissions Policy: In iframes muss das einbettende Dokument die Nutzung erlauben:
allow="idle-detection". - Mindestschwelle:
thresholdmuss 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.
userStateundscreenStatehaben den Wertnull, bisstart()erfolgreich abgeschlossen ist.