使用页面可见性API
概述
页面可见性API可以让你知 道一个页面什么时候是隐藏的,什么时候是显示的.当页面被最小化或者被切换成后台标签页时,浏览器会触发一个 visibilitychange
事件,告诉你用户已经看不到这个页面了,切换到显示状态的时候也同样.你可以给该事件注册监听函数,在页面的可见与不可见状态进行切换时,执行对应的操作.
用处
该API一个很好的用处就是能够在页面切换到不可见状态时暂停执行一些不必要的操作,以减少资源的浪费.
用例
在一个多标签的浏览器中,某个网页所在的标签页很有可能被切换到后台,这时,该网页是用户不可见的. 一些网站很有可能希望在此时做出一些动作. 比如:
- 某网站有个图像幻灯片页面,自动播放图片.如果该页面被切换到了不可见状态,图片的播放操作应该暂停,直到该页面重新对用户可见时,幻灯片才会继续自动播放.
- 某web应用程序每隔一段时间会自动访问服务器更新页面内的及时信息.在页面不可见时,应该停止这种请求动作.
- 某页面想要检测自己是否被预渲染,这样可以获得更准确的页面访问量.
在过去,开发者使用一些不完善的手段间接的实现上述目的.例如通过使用onblur/onfocus
事件,在当前页面失去焦点时得到通知.但这样仍然无法检测到正确的页面可见性(失去焦点并不意味着不可见,等等).如今,页面可见性API可以办到了.
例子
查看在线演示(有声视频,页面不可见时,视频自动暂停.恢复可见时,视频自动播放,下面是实现代码):
// 用来保存视频是否处于暂停状态的变量,由于视频被设置成自动播放,所以这个值默认为"false"
sessionStorage.isPaused = "false";
// 找到当前浏览器支持的hidden属性名和visibilitychange事件名
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") {
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
var videoElement = document.getElementById("videoElement");
// 如果页面被隐藏,暂停视频
// 如果页面被显示,播放视频
function handleVisibilityChange() {
if (document[hidden]) {
videoElement.pause();
} else if (sessionStorage.isPaused !== "true") {
videoElement.play();
}
}
// 如果浏览器不支持addEventListener或页面可见性API,发出警告
if (typeof document.addEventListener === "undefined" || typeof hidden === "undefined") {
alert("This demo requires a browser such as Google Chrome that supports the Page Visibility API.");
} else {
// 注册visibilityChange事件处理函数
document.addEventListener(visibilityChange, handleVisibilityChange, false);
// 页面关闭时,还原该页favicon图标,否则会一直显示paused.png
window.addEventListener("unload", function () {
favicon.change("/favicon.ico");
}, false);
// 当视频暂停时,设置favicon图标为paused.png
videoElement.addEventListener("pause", function () {
favicon.change("images/paused.png");
if (!document[hidden]) {
// 如果不是因为页面被隐藏而暂停的,则把isPaused设置为"true"
sessionStorage.isPaused = "true";
}
}, false);
// 当视频播放时,设置favicon图标为playing.png
videoElement.addEventListener("play", function () {
sessionStorage.isPaused = "false";
favicon.change("images/playing.png");
}, false);
// 设置当前页面的标题为视频已播放时长
videoElement.addEventListener("timeupdate", function () {
document.title = Math.floor(videoElement.currentTime)