简介
作为 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 应用,请参阅其他与性能相关的文章。