页面可见性API属性和事件
目前页面可见性API有两个属性,一个事件,如下:
document.hidden
: Boolean值,表示当前页面可见还是不可见document.visibilityState
: 返回当前页面的可见状态。- “
hidden
“ - “
visible
“ - “
prerender
” 这个表示纳尼呢~~恩,我也不确定,字面意思是“预渲染”。莫非指的是啪啪啪一下子开了很多个选项卡,之前选项卡依然在加载渲染的状态?或者说是浏览器新打开时记住的上一次关闭选项卡的状态?求达人指明! - “
preview
” 预览。根据部分2011年底相关国外部分文章的说法,这种状态出现在,如window7系统下,鼠标放在底部(一般是)任务栏的图标上(预览)的时候。见下截图:
但是根据自己的实际测试,似乎并没有这种状态的改变——包括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);
或者直接调用:
<script src="http://www.zhangxinxu.com/study/201211/pageVisibility.js"></script>
其中具体细节无需关心,实际上上面这么多代码本质上就是下面这点:
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