页面可见性(Page Visibility)API 可以有哪些用途?


CSS中有个有用且有趣且个人比较喜欢的属性 – visibility. 其有两个常用属性值:hidden与visible. 分别表示不可见与可见。OK,本文所说的API中也有Visibility这个单词,那他们表意一致?

回答是:YES! //众人:妹啊,你以为是中国达人秀啊!

页面可见性API就是表示网页可见还是不可见的,巧的是,hidden与visible就是该API的两个状态值。

举个通俗的例子:
如果你在xxxxx.com上浏览提神的图片,则当前你所看的这个网页的visibility就是visible.

此时,如果你老妈子突然进来给你送香蕉,出现下图所示场景:
总是在看桌面

则,此时之前提神的网页的visibility就是hidden – 最小化。

或者老妈子进来的时候,切换到人民网,提神网页的visibility也是hidden – 切换选项卡。

老妈子送的香蕉啦啦啦啦啦

这就是页面可见性API的直观认识,至于其身上哪里有麻子,下面会指出.

三、页面可见性API属性和事件
目前页面可见性API有两个属性,一个事件,如下:

document.hidden: Boolean值,表示当前页面可见还是不可见
document.visibilityState: 返回当前页面的可见状态。
“hidden“
“visible“
“prerender” 这个表示纳尼呢~~恩,我也不确定,字面意思是“预渲染”。莫非指的是啪啪啪一下子开了很多个选项卡,之前选项卡依然在加载渲染的状态?或者说是浏览器新打开时记住的上一次关闭选项卡的状态?求达人指明!
“preview” 预览。根据部分2011年底相关国外部分文章的说法,这种状态出现在,如window7系统下,鼠标放在底部(一般是)任务栏的图标上(预览)的时候。见下截图:
win7鼠标图标程序界面预览 张鑫旭-鑫空间-鑫生活
但是根据自己的实际测试,似乎并没有这种状态的改变——包括IE10浏览器。可能是时代改变,一切都遵循规范了吧。因此,我们重点关注前面三个状态值就可以了。

visibilitychange: 当可见状态改变时候触发的事件。
四、浏览器支持与私有前缀
我写了个如下的页面可见性API支持性的测试代码:

var isPageVisibilitySupport = (function() {
var support = false;
if (typeof window.screenX === “number”) {
[“webkit”, “moz”, “ms”, “o”, “”].forEach(function(prefix) {
if (support == false && document[prefix + (prefix? “H”: “h”) + “idden”] + “” !== “undefined”) {
support = true;
}
});
}
return support;
})();
测试发现,如下浏览器都是支持的:

Chrome 21
FireFox 16.0.2
Opera 12.11
IE10
不支持的浏览器:

IE9
Safari 5.1
因此,typeof document.msHidden != “undefined”可以用来区分IE9浏览器还是IE10浏览器。

正如上面的code所展示的,页面可见性API的所有属性以及事件,目前是需要使用私有前缀的(如果没有这些前缀,浏览器就不认识这些属性或方法了)。
一旦有了前缀,实际应用的时候代码就有些啰哩吧嗦了(可见参见文章底部参考文章中展示的代码)!

因为要一个前缀一个前缀判断——oh, my! 我这个懒人最不喜欢这等麻烦事了,于是,捞起袖子,啪啪啪啪整个一个兼容性的Page Visibility API相关对象,正好包含API中的两个属性以及一个事件。完整代码如下(节省篇幅,滚动显示
):

var pageVisibility = (function() {
var prefixSupport, keyWithPrefix = function(prefix, key) {
if (prefix !== “”) {
// 首字母大写
return prefix + key.slice(0,1).toUpperCase() + key.slice(1);
}
return key;
};
var isPageVisibilitySupport = (function() {
var support = false;
if (typeof window.screenX === “number”) {
[“webkit”, “moz”, “ms”, “o”, “”].forEach(function(prefix) {
if (support == false && document[keyWithPrefix(prefix, “hidden”)] != undefined) {
prefixSupport = prefix;
support = true;
}
});
}
return support;
})();

var isHidden = function() {
    if (isPageVisibilitySupport) {
        return document[keyWithPrefix(prefixSupport, "hidden")];
    }
    return undefined;
};

var visibilityState = function() {
    if (isPageVisibilitySupport) {
        return document[keyWithPrefix(prefixSupport, "visibilityState")];
    }
    return undefined;
};

return {
    hidden: isHidden(),
    visibilityState: visibilityState(),
    visibilitychange: function(fn, usecapture) {
        usecapture = undefined || false;
        if (isPageVisibilitySupport && typeof fn === "function") {
            return document.addEventListener(prefixSupport + "visibilitychange", function(evt) {
                this.hidden = isHidden();
                this.visibilityState = visibilityState();
                fn.call(this, evt);
            }.bind(this), usecapture);
        }
        return undefined;
    }
};    

})(undefined);
或者直接调用:


其中具体细节无需关心,实际上上面这么多代码本质上就是下面这点:

var pageVisibility = {
hidden: Boolean
visibilityState: String
visibilitychange: Function
};
原生属性事件对应关系如下:

pageVisibility.hidden === document.hidden(兼容处理)
pageVisibility.visibilityState=== document.visibilityState(兼容处理)
pageVisibility.visibilitychange(function() { / this指的就是pageVisibility / }); === document.addEventListener(“visibilitychange”, function() {});(兼容处理)
于是,要判断一个浏览器是否支持页面可见性API如下代码就可以了(无需什么webkit或moz或ms等前缀一个个判断了):

var isSupport = typeof pageVisibility.hidden !== “undefined”
测试demo
您可以狠狠地点击这里:兼容性的网页可见性API属性与事件demo

网页可见性 API基本属性与事件实例页面截图 张鑫旭-鑫空间-鑫生活

对于不支持的浏览器,如IE9浏览器,显示的则是”undefined“:
不支持网页可见性API浏览器显示undefined 张鑫旭-鑫空间-鑫生活

OK,万屎具备,只欠草纸了!下面,看看,页面可见性API都有些可以有的实际应用。

//zxx: 下面为广告注意不要勿点嘻嘻~~

五、页面可见性API实际应用
先来看看老外给的一个例子,我觉得很有实际应用价值的。

首先是链接地址:http://www.samdutton.com/pageVisibility/ //zxx: 希望不要明年这个时候被墙掉

进去后,会有一个HTML5 video显示的Google Chrome浏览器广告的30秒funny视频,如下图所示:
视频截图

直接浏览你是看不出什么玄乎的,请切换一个选项卡,让该页面置于后面,结果,您会发现这个选项卡的标题栏变成了这样:
标题栏显示视频暂停以及暂停时间

看出来没?视频播放被中断了——当page不可见的时候,视频会自动暂停!

此时,您再进入该选项卡,视频又从刚才的地方继续播放了,如下截图:
页面可见视频继续播放 张鑫旭-鑫空间-鑫生活

个人愚见,国内的一些视频站点是不是可以应用下这个API呢!这样当妈妈进来送香蕉的时候,直接win+D显示桌面就可以了,声音啊什么的会自动关掉,振奋视频自动暂停,多赞的一个功能啊!以前的暂停视频+最小化浏览器直接变成了一步→最小化,节约了大量的宝贵时间,极大了提升了用户体验,恩!不错!!

上面的例子毕竟长在外人田啊,一旦建起了围墙就看不到了,因此,自己折腾了一个简单的10秒钟低质量的猫猫版本。//zxx: 上面例子视频3M+,我估算了下,1000次访问的话,我勒个去,差不多3个G的流量去了,我现在每月流量都岌岌可危,因此,大家将就下下这个百来K的视频(Chrome浏览器以及IE10下可访问,或者谁给我尺寸小一点的ogv格式任意视频,让FireFox也能OK)~~

您可以狠狠地点击这里:10秒钟妈妈来自动暂停视频demo

操作同上,进入页面播放,离开页面暂停。
Chrome浏览器下效果截图 张鑫旭-鑫空间-鑫生活

登录同步
这是我想的一个觉得蛮实用的应用。有如下场景:

  1. 去淘宝买东西,未登录状态下,进入首页。
  2. 然后新窗口打开任意页面,登录并成功返回。
    淘宝网成功登录 张鑫旭-鑫空间-鑫生活
  3. 再次访问刚才打开的首页,发现页面还是未登录状态(见下图),实际上用户已经登录了。
    之前的首页仍然是未登录状态

目前,这种状态大家似乎习以为常,觉得很OK,实际上这种糟糕的。就像没有空调的岁月里,人们觉得风扇很OK啊;但是,现在呢,还有谁屋顶吊个风扇吗!!有了页面可见性API,我们可以把体验做地更好。

您可以狠狠地点击这里:网页可见性API与登录同步demo

不出意外,您默认进来应该是提示你登录的:

点击上图所示的“登录”文字链接,会在新窗口无刷新登录。任意用户名和密码,成功后再回到之前提示的登录页面,已经变成了:“欢迎回来,某某某”了!

只要该页面不被关闭,你怎样刷新,都是“欢迎回来,某某某”。不过,在实际应用中,检测到已经登录成功,直接刷新当前页面的居多!IE10下,貌似本地存储无法同源不同页面共享,这使得通过HTML5本地存储共享信息的做法遇到了些许阻碍。

精确的在线时长
这个不用多说,只有用户当前这个页面可见的时候,才计算在线时间,这样可以避免挂机的情况,时长计算更准确(这个可能不是个好idea)。

在线聊天离开状态
网页聊天的时候,可以知道用户是否“离开”还是“离线”还是“下线”。当前页面不可见,但连接还在的时候,我们可以确定该人是离开的(涉及隐私,可能也不是个好idea)。

以及其他些应用需求
等到了实际需求的时候,就会想到页面可见性API,看看能不能渐进增加下用户体验等。

六、结语
脑细胞不够用了,肯定还有很多现有的可以应用在实际项目中的idea的,一时想不出——恩,比方说,每次用户切换到你这个页面上的时候,logo抖一下,或页面一道亮光闪过,后者欢迎语之类……总之,是个很有用很有趣的API.

此API支持日趋稳定,不会有被去除的可能,因此,大伙儿可以放心大胆尝试之……因为是新东西,您的任何小小idea都会是首创,领先的创造者——开动你的脑筋,发挥你的创造性思维,让我们的网页更加生动多彩吧!

文章目录
  1. 1.
|