Page Visibility API 用于感知页面可见性状态,核心是读取 document.visibilityState("visible"/"hidden"/"prerender")或 document.hidden,并监听 visibilitychange 事件;它原生可靠,适用于暂停/恢复媒体、定时器及统计真实停留时长。

用 Page Visibility API 感知页面状态,核心就两件事:读取当前状态 + 监听状态变化。它不依赖定时轮询,也不受标签页切换、锁屏、最小化等场景干扰,是浏览器原生支持的可靠方案。
直接读取当前可见性状态
页面加载后,立刻就能知道它此刻是否可见:
- document.visibilityState 返回字符串,值为 "visible"(至少部分可见)、"hidden"(完全不可见,如切走标签页、锁屏、最小化)或极少用的 "prerender"
- document.hidden 是布尔简写,true 表示隐藏,false 表示可见,兼容性略好于 visibilityState
监听状态切换事件
比手动查状态更实用的是监听变化,避免遗漏关键时机:
- 在 DOMContentLoaded 后绑定 visibilitychange 事件,确保不会错过首次切换
- 事件触发时,检查 document.visibilityState 就能知道刚变成什么状态
- iOS Safari 后台可能冻结定时器,但这个事件仍会正常触发,适合做暂停逻辑
典型使用场景举例
状态感知不是为了“知道”,而是为了“响应”:
立即学习“Java免费学习笔记(深入)”;
- 页面变 hidden 时:暂停轮播图、停止 setInterval 轮询、调用 video.pause()
- 页面变 visible 时:恢复动画、重置计时器、调用 video.play()(注意自动播放策略)
- 统计真实停留时长:只在 visible 状态下累计时间,hidden 时立即上报或暂存
注意边界情况
有些状态看似相似,但行为和触发条件不同:
- pagehide 和 beforeunload 不一定总触发(尤其移动端后台杀进程),不能替代 visibilitychange
- unloaded 状态在部分浏览器中不被支持,实际开发中可忽略
- 页面被部分遮挡但仍有像素可见,visibilityState 仍是 visible,这是设计使然


















