visibilitychange事件是检测页面可见性变化的标准方法,通过监听document.visibilityState值为'hidden'或'visible'来准确判断用户离开或返回,比blur/focus更精准,但不能替代beforeunload/pagehide用于退出确认或资源清理。

用 visibilitychange 事件检测用户离开页面,核心是监听 document.visibilityState 的变化,而不是简单判断“页面失焦”或“窗口关闭”。
监听 visibilitychange 事件
这是标准、可靠的方式。只要页面可见性状态改变(比如切标签、最小化、锁屏),就会触发该事件:
- 给
document添加监听器,回调中检查document.visibilityState - 值为
'hidden'时,说明用户已离开当前页面(不可见) - 值为
'visible'时,说明用户返回了(重新可见)
示例代码:
<script>document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
console.log('用户离开了:页面不可见');
// 暂停视频、停止轮播、暂停轮询等
} else if (document.visibilityState === 'visible') {
console.log('用户回来了:页面可见');
// 恢复播放、重启动画等
}
});
</script>
区分 hidden 和 visible 的实际含义
visibilityState 的判断逻辑更贴近真实场景,比 blur/focus 更精准:
-
'visible':页面至少部分在前台显示(包括任务栏预览、多窗口并排时露出一角) -
'hidden':页面完全不可见——涵盖切换标签页、最小化窗口、锁屏、系统切换到其他 App(含手机端)、页面即将卸载等 -
'prerender':极少见,仅用于预渲染场景,可忽略
注意:document.hidden 已废弃,应优先使用 document.visibilityState。
它不能替代 beforeunload / pagehide
visibilitychange 不代表页面正在关闭:
- 当用户关闭标签页时,通常先触发
visibilitychange(变为hidden),再触发pagehide或beforeunload - 若需执行退出前确认(如防止误关导致数据丢失),仍要监听
beforeunload并返回提示字符串 - 若需清理资源或上报最终行为(如统计停留时长),建议组合使用
visibilitychange+pagehide
常见误判场景与规避建议
有些行为看似“离开”,但其实不会触发 visibilitychange:
- 点击地址栏、弹出 alert、打开开发者工具、聚焦控制台——这些只触发
blur,不改变可见性 - iframe 中隐藏子页面,不会触发其自身的
visibilitychange(子页面可见性跟随父页面) - 移动端后台进程被系统回收时,
visibilitychange仍会触发hidden,是目前最稳定的兜底方案
所以,做考试监控、网课防切屏、自动暂停视频等,首选 visibilitychange;但涉及强制留人、数据保存确认等,需额外补充 beforeunload。


















