简介
作为 Web 开发者,我们往往会对能够帮助我们打造更具吸引力、更具互动性的 Web 网页的新技术感到兴奋。使用 WebGL 的 3D 图形?当然可以。使用 WebAudio 实现高级音频功能?没问题。使用网络摄像头和麦克风的实时协作应用?我要注册!
虽然不那么引人注目,但同样重要的是,我们可以利用这些技术构建运行效率更高且提供更好整体用户体验的应用。这正是 PageVisibility 等 API 的用武之地。
Page Visibility API 执行一项简单但重要的功能,即让您的应用知道网页何时对用户可见。借助这项基本信息,您可以创建在用户未查看时表现出不同行为的网页。我们来看几个示例:
- 如果网页从服务器检索信息,但没有被用户主动查看,则其更新周期可能会放缓
- 显示轮播图片或视频/音频内容的页面可以暂停,直到用户再次显示该页面
- 应用可以决定仅在视图隐藏时向用户显示通知
乍一看,除了方便用户之外,此 API 似乎没有什么用处,但考虑到移动网络浏览量大幅增加,任何有助于节省设备电池电量的功能都非常重要。通过使用 PageVisibility API,您的网站可以帮助用户设备降低功耗并延长续航时间。
截至撰写本文时,处于“候选建议”阶段的 API 规范同时提供了用于检测文档可见性状态的属性,以及响应可见性更改的事件。
在本教程中,我将介绍该 API 的基础知识,并展示如何将其应用于一些实际示例(如果您不耐烦,可以直接跳到这些示例)。
文档公开范围属性
PageVisibilityAPI 规范的当前版本定义了两个文档属性:布尔值 hidden
和枚举 visibilityState
。visibilityState 属性目前有四个可能的值:hidden
、visible
、prerender
和 unloaded
。
正如您所料,当文档完全不可见时,hidden 属性会返回 true。通常,这意味着文档已最小化、位于后台标签页中、操作系统的锁屏已开启等。如果文档的任何部分至少在一个显示屏上至少部分可见,则将此属性设为 false。此外,为了适应无障碍工具,当屏幕放大镜等工具完全遮盖文档,但仍在显示文档的视图时,可以将 hidden 属性设为 false。
处理供应商前缀
为了将重点放在代码上,而不是所有特定于供应商的接头,我将使用一些辅助函数来隔离特定于浏览器的代码。一旦取消对 Android 4.4 浏览器的支持,您就可以移除此部分并继续使用标准名称。
function getHiddenProp(){
var prefixes = ['webkit','moz','ms','o'];
// if 'hidden' is natively supported just return it
if ('hidden' in document) return 'hidden';
// otherwise loop over all the known prefixes until we find one
for (var i = 0; i < prefixes.length; i++){
if ((prefixes[i] + 'Hidden') in document)
return prefixes[i] + 'Hidden';
}
// otherwise it's not supported
return null;
}
文档属性示例
现在,我们可以编写一个跨浏览器函数 isHidden()
,以查看文档是否可见。
function isHidden() {
var prop = getHiddenProp();
if (!prop) return false;
return document[prop];
}
如需更精细地了解文档的可见性,您可以使用 visibilityState 属性。此属性会返回以下四个值之一:
hidden
:文件完全隐藏visible
:文档至少在一个显示设备上有部分内容可见prerender
:文档在屏幕外加载且不可见(此值为可选值;并非所有浏览器都一定支持)unloaded
:如果要卸载文档,则返回此值(此值是可选值;并非所有浏览器都支持该值)
VisibilityChange 事件
除了可见性属性之外,还有一个 visibilitychange 事件,该事件会在文档的可见性状态发生变化时触发。您可以直接在文档对象上为此事件注册事件监听器:
事件示例
// use the property name to generate the prefixed event name
var visProp = getHiddenProp();
if (visProp) {
var evtname = visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
document.addEventListener(evtname, visChange);
}
function visChange() {
var txtFld = document.getElementById('visChangeText');
if (txtFld) {
if (isHidden())
txtFld.value += "Tab Hidden!\n";
else
txtFld.value += "Tab Visible!\n";
}
}
摘要
构建出色的 Web 应用不仅仅是使用用户可以看到和互动的炫酷醒目功能,还需要考虑更多方面。真正出色的应用会妥善利用用户的资源和注意力,而 Page Visibility API 是其中的重要一环。如需详细了解如何构建资源感知型 Web 应用,请参阅我们的其他性能相关文章。