Created
May 18, 2013 01:23
-
-
Save markyun/5602870 to your computer and use it in GitHub Desktop.
Page Visibility (浏览器提供的 API 来直接判断页面的可见性)
:Page Visibility 正式成为 W3C 推荐规范,用户喜欢一次性打开多个页面,然后逐个查看。随着标签页成为浏览器的标配,当页面处于不可见状态时,UI 绘制、更新轮询等代码执行,往往可以停下来或频率变慢,这可以节省 CPU 等硬件损耗。对移动设备来说特别重要,能延长电池续航时间。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
源:玉伯 | |
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