Signatur
Beschreibung
document.visibilityState ist Teil der Page Visibility API. Die Eigenschaft sagt dir, ob der Inhalt der Seite für den Nutzer gerade sichtbar ist. Sie ist "hidden", wenn der Tab im Hintergrund liegt, das Fenster minimiert ist, der Bildschirm gesperrt ist oder das Betriebssystem die Seite ausblendet. Sonst ist sie "visible".
Brauchbar ist das vor allem, um Ressourcen zu sparen und das Verhalten an die Situation anzupassen. Typische Fälle sind: Polling oder Animationen anhalten, Videos oder Audio pausieren, Analytics-Sitzungen beenden oder Daten ein letztes Mal sichern, bevor ein mobiler Browser die Seite einfriert oder beendet.
Normalerweise liest man den Wert im Handler des Events visibilitychange. Dieses Event wird auf document ausgelöst, sobald sich visibilityState ändert. Du kannst es mit document.addEventListener("visibilitychange", handler) abonnieren oder über document.onvisibilitychange setzen.
Mögliche Werte:
"visible": Die Seite ist zumindest teilweise sichtbar, liegt also im Vordergrund-Tab eines nicht minimierten Fensters."hidden": Die Seite ist für den Nutzer nicht sichtbar."prerender"(veraltet): Früher gab es diesen Wert für vorab gerenderte Seiten. Er ist aus der Spezifikation entfernt, und moderne Browser liefern ihn nicht mehr.
Rückgabewert
Beispiele
Aktuellen Zustand abfragen
// Beim Laden prüfen, ob die Seite sichtbar ist
console.log(`Sichtbarkeit: ${document.visibilityState}`);
if (document.visibilityState === "hidden") {
console.log("Seite wurde im Hintergrund geöffnet");
}
Video pausieren, wenn der Tab verborgen wird
const video = document.querySelector("video");
const handleVisibility = () => {
if (document.visibilityState === "hidden") {
video.pause();
} else {
video.play().catch(() => {
// Autoplay kann vom Browser blockiert werden
});
}
};
document.addEventListener("visibilitychange", handleVisibility);
// Später aufräumen, z. B. beim Verlassen einer SPA-Ansicht
// document.removeEventListener("visibilitychange", handleVisibility);
Polling nur im sichtbaren Zustand
let timerId = null;
const fetchUpdates = async () => {
const res = await fetch("/api/updates");
const data = await res.json();
console.log("Neue Daten:", data);
};
const startPolling = () => {
if (timerId === null) timerId = setInterval(fetchUpdates, 10_000);
};
const stopPolling = () => {
clearInterval(timerId);
timerId = null;
};
document.onvisibilitychange = () => {
document.visibilityState === "visible" ? startPolling() : stopPolling();
};
if (document.visibilityState === "visible") startPolling();
Analytics-Daten beim Verbergen zuverlässig senden
const sessionStart = performance.now();
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
const payload = JSON.stringify({
dauerMs: Math.round(performance.now() - sessionStart),
});
// sendBeacon funktioniert auch, wenn die Seite gleich entladen wird
navigator.sendBeacon("/analytics", payload);
}
});
// Wichtig · Fallstricke
- Anstelle von
unload/beforeunload: Auf Mobilgeräten werdenunload-Events oft gar nicht ausgelöst. Der Wechsel auf"hidden"ist in vielen Fällen der letzte Moment, auf den man sich verlassen kann, um Daten zu sichern oder pernavigator.sendBeacon()zu senden. - Nicht gleich Fokus: Eine Seite kann
"visible"sein, ohne den Fokus zu haben, etwa wenn ein anderes Fenster darüber liegt, sie aber nicht ganz verdeckt. Den Fokus prüfst du mitdocument.hasFocus()bzw. den Eventsfocus/blur. - Verdeckte Fenster: Ob ein Fenster, das von anderen Fenstern vollständig verdeckt ist, als
"hidden"gilt, hängt von Browser und Betriebssystem ab. "prerender"ist veraltet: Prüfe Bedingungen immer ausdrücklich auf=== "visible"bzw.=== "hidden".- Timer im Hintergrund: Browser drosseln
setTimeout/setIntervalin verborgenen Tabs ohnehin stark, undrequestAnimationFrameläuft dort gar nicht. Verlass dich also nicht auf genaues Timing im Zustand"hidden". - Kompatibilität: Wird von allen modernen Browsern ohne Präfix unterstützt. Sehr alte Versionen (vor ca. 2013) kannten nur Varianten mit Präfix wie
webkitVisibilityState. Die ältere Eigenschaftdocument.hiddenist ein boolesches Gegenstück.