前言
今天主要介绍2个api,一个是Page Visibility API,一个是Page Lifecycle API,这两个api你可能用的不多,关于Page Visibility API,目前大部分主流浏览器已经支持。
Page Visibility API主要是监听网页是否隐藏,是否可见。Page Lifecycle API可以让我们对整个网页的生命周期有了更好的把控能力。
Page Visibility API
首先,我介绍一下Page Visibility API的应用场景
用户对我们的h5页面进行如下操作
1、用户点击了一条系统通知,切换到另一个 App。
2、用户进入任务切换窗口,切换到另一个 App。
3、用户点击了 Home 按钮,切换回主屏幕。
4、操作系统自动切换到另一个 App(比如,收到一个电话)
Page Visibility API 的意义在于,通过监听网页的可见性,对网页中如下相关信息进行暂停或者启用:
1、网页中音频,和视频,在网页不可见是暂停,可见时继续播放
2、网页中的动画,在网页不可见是暂停,可见时继续播放
3、对服务器的轮询等
使用
document.visibilityState
可以返回如下状态
hidden:页面彻底不可见。
visible:页面至少一部分可见。
prerender:页面即将或正在渲染,处于不可见状态。
visibilitychange // 事件
只要document.visibilityState属性发生变化,就会触发visibilitychange事件。因此,可以通过监听这个事件(通过document.addEventListener()方法或document.onvisibilitychange属性),跟踪页面可见性的变化。
document.addEventListener('visibilitychange', function () {
// 用户离开了当前页面
if (document.visibilityState === 'hidden') {
console.log('haorooms测试-页面不可见');
//进行你的代码逻辑操作
}
// 用户打开或回到页面
if (document.visibilityState === 'visible') {
console.log('haorooms测试-页面可见');
//进行你的代码逻辑操作
}
});
与今天介绍的这2个API相关的还有pagehide、beforeunload、unload等事件,这些事件我之前也介绍过,请分别点击查看!
Page Lifecycle API
Android、iOS 和最新的 Windows 系统可以随时自主地停止后台进程,及时释放系统资源。也就是说,网页可能随时被系统丢弃掉。Page Lifecycle API 可以监听是否被系统挂起或者弃掉。
这个API可以分为如下几个阶段
(1)Active 阶段
在 Active 阶段,网页处于可见状态,且拥有输入焦点。
对应focus 事件
focus事件在页面获得输入焦点时触发,比如网页从 Passive 阶段变为 Active 阶段
(2)Passive 阶段
在 Passive 阶段,网页可见,但没有输入焦点,无法接受输入。UI 更新(比如动画)仍然在执行。该阶段只可能发生在桌面同时有多个窗口的情况。
对应blur事件在页面失去输入焦点时触发,比如网页从 Active 阶段变为 Passive 阶段。
(3)Hidden 阶段
在 Hidden 阶段,用户的桌面被其他窗口占据,网页不可见,但尚未冻结。UI 更新不再执行。
对应上面的visibilitychange 事件,可以通过网页是否可见来判断
(4)Terminated 阶段
在 Terminated 阶段,由于用户主动关闭窗口,或者在同一个窗口前往其他页面,导致当前页面开始被浏览器卸载并从内存中清除。注意,这个阶段总是在 Hidden 阶段之后发生,也就是说,用户主动离开当前页面,总是先进入 Hidden 阶段,再进入 Terminated 阶段。
这个阶段会导致网页卸载,任何新任务都不会在这个阶段启动,并且如果运行时间太长,正在进行的任务可能会被终止。
beforeunload事件在窗口或文档即将卸载时触发。该事件发生时,文档仍然可见,此时卸载仍可取消。经过这个事件,网页进入 Terminated 状态。
(5)Frozen 阶段
如果网页处于 Hidden 阶段的时间过久,用户又不关闭网页,浏览器就有可能冻结网页,使其进入 Frozen 阶段。不过,也有可能,处于可见状态的页面长时间没有操作,也会进入 Frozen 阶段。
这个阶段的特征是,网页不会再被分配 CPU 计算资源。定时器、回调函数、网络请求、DOM 操作都不会执行,不过正在运行的任务会执行完。浏览器可能会允许 Frozen 阶段的页面,周期性复苏一小段时间,短暂变回 Hidden 状态,允许一小部分任务执行。
这个阶段可能有 freeze事件
可以通过document.onfreeze属性指定在进入 Frozen 阶段时调用的回调函数。
function handleFreeze(e) {
// Handle transition to FROZEN
}
document.addEventListener('freeze', handleFreeze);
# 或者
document.onfreeze = function() { ... }
也可能有resume 事件
resume事件在网页离开 Frozen 阶段,变为 Active / Passive / Hidden 阶段时触发。
document.onresume属性指的是页面离开 Frozen 阶段、进入可用状态时调用的回调函数。
function handleResume(e) {
// handle state transition FROZEN -> ACTIVE
}
document.addEventListener("resume", handleResume);
# 或者
document.onresume = function() { ... }
(6)Discarded 阶段
如果网页长时间处于 Frozen 阶段,用户又不唤醒页面,那么就会进入 Discarded 阶段,即浏览器自动卸载网页,清除该网页的内存占用。不过,Passive 阶段的网页如果长时间没有互动,也可能直接进入 Discarded 阶段。
如果某个选项卡处于 Frozen 阶段,就随时有可能被系统丢弃,进入 Discarded 阶段。如果后来用户再次点击该选项卡,浏览器会重新加载该页面。
这时,可以通过判断document.wasDiscarded属性,了解先前的网页是否被丢弃了
if (document.wasDiscarded) {
// 该网页已经不是原来的状态了,曾经被浏览器丢弃过
// 恢复以前的状态
getPersistedState(self.discardedClientId);
}
注:目前 Page Lifecycle API 仅支持Chrome 68及以上版本 ,要兼容低版本浏览器可以用PageLifecycle.js