This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2021.
The visibilitychange event is fired at the document when the contents of its tab have become visible or have been hidden.
The event is not cancelable.
Use the event name in methods like addEventListener(), or set an event handler property.
addEventListener("visibilitychange", (event) => { })
onvisibilitychange = (event) => { }
A generic Event.
The event doesn't include the document's updated visibility status, but you can get that information from the document's visibilityState property.
This event fires with a visibilityState of hidden when a user navigates to a new page, switches tabs, closes the tab, minimizes or closes the browser, or, on mobile, switches from the browser to a different app. Transitioning to hidden is the last event that's reliably observable by the page, so developers should treat it as the likely end of the user's session (for example, for sending analytics data).
The transition to hidden is also a good point at which pages can stop making UI updates and stop any tasks that the user doesn't want to have running in the background.
This example pauses playing audio when the page is hidden and resumes playing when the page becomes visible again. For a full example, see the Page Visibility API: Pausing audio on page hide documentation.
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
playingOnHide = !audio.paused;
audio.pause();
} else if (playingOnHide) {
// Resume playing if audio was "playing on hide"
audio.play();
}
});
This example treats the transition to hidden as the end of the user's session, and sends the appropriate analytics using the Navigator.sendBeacon() API:
document.onvisibilitychange = () => {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", analyticsData);
}
};
| Desktop | Mobile | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android | WebView on iOS | |
visibilitychange_event |
6213Theonvisibilitychange event handler property is not supported.33–62Theonvisibilitychange event handler property is not supported. |
1812–18Theonvisibilitychange event handler property is not supported. |
56 | 4915Theonvisibilitychange event handler property is not supported.20–49Theonvisibilitychange event handler property is not supported.12.1–15Theonvisibilitychange event handler property is not supported. |
14.114–14.1Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.10.1–14["Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.", "Before Safari 14, the event does not bubble, so document.addEventListener('visibilitychange', ...) works, but window.addEventListener('visibilitychange', ...) does not."]7–10.1["Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.", "Before Safari 14, the event does not bubble, so document.addEventListener('visibilitychange', ...) works, but window.addEventListener('visibilitychange', ...) does not.", "The onvisibilitychange event handler property is not supported."] |
6218Theonvisibilitychange event handler property is not supported.33–62Theonvisibilitychange event handler property is not supported. |
56 | 4614Theonvisibilitychange event handler property is not supported.20–46Theonvisibilitychange event handler property is not supported.12.1–14Theonvisibilitychange event handler property is not supported. |
14.514–14.5Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.10.3–14["Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.", "Before Safari on iOS 14, the event does not bubble, so document.addEventListener('visibilitychange', ...) works, but window.addEventListener('visibilitychange', ...) does not."]7–10.3["Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.", "Before Safari on iOS 14, the event does not bubble, so document.addEventListener('visibilitychange', ...) works, but window.addEventListener('visibilitychange', ...) does not.", "The onvisibilitychange event handler property is not supported."] |
8.01.0Theonvisibilitychange event handler property is not supported.2.0–8.0Theonvisibilitychange event handler property is not supported. |
624.4Theonvisibilitychange event handler property is not supported.4.4.3–62Theonvisibilitychange event handler property is not supported. |
14.514–14.5Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.10.3–14["Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.", "Before WebView on iOS 14, the event does not bubble, so document.addEventListener('visibilitychange', ...) works, but window.addEventListener('visibilitychange', ...) does not."]7–10.3["Doesn't fire thevisibilitychange event when navigating away from a document, so also include code to check for the pagehide event (which does fire for that case in all current browsers). See bug 116769, bug 151234, bug 151610, and bug 194897.", "Before WebView on iOS 14, the event does not bubble, so document.addEventListener('visibilitychange', ...) works, but window.addEventListener('visibilitychange', ...) does not.", "The onvisibilitychange event handler property is not supported."] |
Document.visibilityStateDocument.hiddenvisibilitychange, not beforeunload/unload.
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event