Page Visibility(页面可见性) API

在HTML 5中,新增一个Page Visibility API,该API允许开发者知道一个Web页面在何时变为可见或获取焦点。当用户在多浏览器标签之间进行切换时,对用户来说,Web页面可能从可见状态变为不可见状态。在Page Visibility API中,当用户将Web页面最小化或将当前浏览器标签切换到其他标签时,将会触发一些事件,开发者可以指定在该事件中所需执行的处理。例如,当应用程序正在播放一个视频时,用户可能会临时将浏览器标签切换到其他标签,在查看完其他标签页后再切换回应用程序所属标签。这时用户希望当浏览器被切换到其他标签时视频能够暂停播放,当浏览器从其他标签切换回应用程序所属标签时视频能够继续播放。

具体来说,Page Visibility API适用于如下所示的一些场合:
一个应用程序中具有多幅图片的幻灯片式的连续播放功能,当页面处于不可见状态时,图片停止播放,当页面变为可见状态时,图片继续播放。
在一个实时显示服务器端信息的应用程序中,当页面处于不可见状态时,停止定期向服务器端请求数据的处理,当页面变为可见状态时,继续执行定期向服务器端请求数据的处理。
在一个具有播放视频功能的应用程序中,当页面处于不可见状态时,暂停播放视频,当页面变为可见状态时,继续播放视频。

在使用Page Visibility API的时候,我们首先需要判断当前用户所使用的浏览器以及该浏览器是否支持Page Visibility API,代码如下所示

// 如果使用的浏览器为Firefox浏览器且支持Page Visibility API
if (typeof document.mozHidden !== "undefined") {
    // 代码略
}
// 如果使用的浏览器为IE浏览器且支持Page Visibility API
else if (typeof document.msHidden !== "undefined") {
    // 代码略
}
// 如果使用的浏览器为Chrome浏览器且支持Page Visibility API
else if (typeof document.webkitHidden !== "undefined") {
    // 代码略
}
// 如果使用的浏览器为其他浏览器且支持Page Visibility API
else if (typeof document.hidden !== "undefined") {
    // 代码略
}

在Page Visibility API中,可以通过document对象的hidden属性值(在Firefox浏览器中为mozHidden属性值,在IE浏览器中为msHidden属性值,在Chrome及Opera浏览器中为webkitHidden属性值)来判断页面是否处于可见状态,当页面处于可见状态时属性值为false,当页面处于不可见状态时属性值为true。
在Page Visibility API中,可以通过document对象的visibilityState属性值来判断页面的可见状态。该属性值为一个字符串值,其含义如下所示:
1)visible:页面至少部分可见,当前页面位于用户正在查看的浏览器标签窗口中且浏览器窗口未被最小化。
2)hidden:页面内容对用户不可见。当前页面不在用户正在查看的浏览器标签窗口中或浏览器窗口已被最小化。
3)prerender:页面内容已被预渲染,但是对用户不可见(关于页面预渲染的详细信息,可以参考Chrome浏览器的Prerender API中的内容)。

示例页面中具有一个video元素与一个“播放”按钮,用户单击“播放”按钮时按钮文字变为“暂停”,同时开始播放video元素中的视频,当页面变为最小化状态或用户将浏览器标签切换到其他标签时,视频暂停播放;当页面恢复正常状态或用户将浏览器标签切换回页面所在标签时,视频继续播放;当用户单击“暂停”按钮时,按钮文字变为“播放”,视频暂停播放。

    <video id="videoElement" src="BigBuck.webm" controls></video><br/>
    <button id="btnPlay" onclick="PlayOrPause()">播放</button>
var hidden, visibilityChange,videoElement;
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";
}
document.addEventListener(visibilityChange, handleVisibilityChange,
false);
function window_onload(){
    videoElement= document.getElementById("videoElement");
    videoElement.addEventListener('ended',videoEnded,false);
    videoElement.addEventListener('play',videoPlay,false);
    videoElement.addEventListener('pause',videoPause,false);
}
// 如果页面变为不可见状态,则暂停视频播放;
// 如果页面变为可见状态,则继续视频播放;
function handleVisibilityChange() {
    if (document[hidden]) {
        videoElement.pause();
    }
    else {
        videoElement.play();
    }
}
function play()
{
    // 播放视频
    videoElement.play();
}
function pause()
{
    // 暂停播放
    videoElement.pause();
}
function PlayOrPause()
{
    if(videoElement.paused)
    {
        videoElement.play();
    }
    else
        videoElement.pause();
}
function videoEnded(ev)
{
    videoElement.currentTime=0;
    this.pause();
}
function videoPlay(ev)
{
    var btnPlay=document.getElementById("btnPlay");
    btnPlay.innerHTML="暂停";
}
function videoPause(ev)
{
    var btnPlay=document.getElementById("btnPlay");
    btnPlay.innerHTML="播放";
}