这个API 的意义在于通过监听网页的可见性,可以监听当前页面是否可见(最小化?关闭?正常展示?),从而可以用来节省资源,减缓电能的消耗。比如,一旦用户不看网页,对服务器的轮询、网页动画、正在播放的音频或视频都是可以暂停的。
document.visibilityState
这个API其实就是在document对象上新增了一个document.visibilityState属性,并可以返回一个字符串用用来表示页面当前的可见性状态,共有三个可能的值:
-
hidden:页面彻底不可见。
-
visible:页面至少一部分可见。
-
prerender:页面即将或正在渲染,处于不可见状态。
其中,hidden状态和visible状态是所有浏览器都必须支持的。prerender状态只在支持"预渲染"的浏览器上才会出现,比如 Chrome 浏览器就有预渲染功能,可以在用户不可见的状态下,预先把页面渲染出来,等到用户要浏览的时候,直接展示渲染好的网页。
只要页面可见,哪怕只露出一个角,document.visibilityState属性就返回visible。只有以下四种情况,才会返回hidden。
-
浏览器最小化。
-
浏览器没有最小化,但是当前页面切换成了背景页。
-
浏览器将要卸载(unload)页面。
-
操作系统触发锁屏屏幕。
可以看到,上面四种场景涵盖了页面可能被卸载的所有情况。也就是说,页面卸载之前,document.visibilityState属性一定会变成hidden。事实上,这也是设计这个 API 的主要目的。
另外,早期版本的 API,这个属性还有第四个值unloaded,表示页面即将卸载,现在已经被废弃了。
注意:document.visibilityState属性只针对顶层窗口,内嵌的页面的document.visibilityState属性由顶层窗口决定。使用 CSS 属性隐藏页面(比如display: none;),并不会影响内嵌页面的可见性。
visibilitychange 事件
只要document.visibilityState属性发生变化,就会触发visibilitychange事件。因此,可以通过监听这个事件(通过document.addEventListener()方法或document.onvisibilitychange属性),跟踪页面可见性的变化。
document.addEventListener('visibilitychange', function () {
// 用户离开了当前页面
if (document.visibilityState === 'hidden') {
document.title = '页面不可见';
}
// 用户打开或回到页面
if (document.visibilityState === 'visible') {
document.title = '页面可见';
}
});
上面代码是 Page Visibility API 的最基本用法,可以监听可见性变化。
下面是另一个例子,一旦页面不可见,就暂停视频播放。
var useMedia = document.getElementById('video');
document.addEventListener('visibilitychange', offVideo);
function offVideo() {
if (document.visibilityState === 'hidden') {
useMedia.pause();
} else if (document.visibilityState === 'visible') {
useMedia.play();
}
}
页面卸载
页面卸载可以分成三种情况:
-
页面可见时,用户关闭 Tab 页或浏览器窗口。
-
页面可见时,用户在当前窗口前往另一个页面。
-
页面不可见时,用户或系统关闭浏览器窗口。
这三种情况,都会触发visibilitychange事件。前两种情况,该事件在用户离开页面时触发;最后一种情况,该事件在页面从可见状态变为不可见状态时触发。