Skip to content

Instantly share code, notes, and snippets.

@markyun
Created May 18, 2013 01:23
Show Gist options
  • Save markyun/5602870 to your computer and use it in GitHub Desktop.
Save markyun/5602870 to your computer and use it in GitHub Desktop.
Page Visibility (浏览器提供的 API 来直接判断页面的可见性) :Page Visibility 正式成为 W3C 推荐规范,用户喜欢一次性打开多个页面,然后逐个查看。随着标签页成为浏览器的标配,当页面处于不可见状态时,UI 绘制、更新轮询等代码执行,往往可以停下来或频率变慢,这可以节省 CPU 等硬件损耗。对移动设备来说特别重要,能延长电池续航时间。
源:玉伯
document.hidden 是布尔值,true 表示页面可见,false 表示不可见。
向后兼容
为什么要是 document.hidden,而不是 document.visible?如果设计成 document.visible,那么 true 表示可见,false 表示不可见,是多么自然的事情啊。
我们从代码使用上入手来想想。如果设计成 document.visible,很容易写出:
if (document.visible) {
// 页面可见时的正常逻辑
} else {
// 页面不可见时,减少点资源占用
}
上面的代码初看没什么问题,但作为前端,眼尖一点不难发现是有问题的:
在尚不支持 Page Visibility API 的浏览器中,document.visible 的值是 undefined.
为了让代码在老浏览器里也没问题,一种可行的写法是:
// 在老浏览器上,始终判定页面为可见
if ( typeof document.visible === 'undefined' || document.visible === true) {
// 页面可见时的正常逻辑
} else {
// 页面不可见时,减少点资源占用
}
上面这种写法,需要一定经验才能写出来。否则稍不留意,就会掉坑里。
如果设计成 document.hidden,则一切简单多了:
if (document.hidden) {
// 页面不可见时,减少点资源占用
}
老浏览器上,document.hidden 取值为 undefined,可以当做布尔值 false 来使用。
这是 API 设计上的一种向后兼容。给任何现有体系增加新接口,都需要仔细考虑场景,做到向前的功能增强,同时向后也能合理兼容。
可扩展性
还有一个接口是:
document.visibilityState
规范中明确可取的值是:visible、hidden、prerender、unloaded
作为枚举值,最大的好处是,可以方便增加新状态。比如页面所在浏览器窗口被其他窗口完全遮挡住时,visibilityState 的取值可以是 obscured. 虽然目前没有这个状态值,但未来如果真的有需求,就可以很方便添加上。
这是 API 可扩展性设计中很小的一个点,优美往往隐藏在细节里。
一致性
最后想说的接口是 visibilityState 属性值发生变化时的事件:visibilitychange 。
为什么不是 visibilityChange? 或 change:visibility 等命名?
命名永远是计算机科学里的两大难题之一。
对于前端来说,下面这些 DOM 事件不应该陌生:
mousedown
mousemove
keypress
keyup
touchstart
dragleave
readystatechange
propertychange
有了上面这些事件名作为参考,visibilitychange 看着就非常舒服了。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment