简介
作为 Web 开发者,我们往往会对能够让我们创建更具吸引力、互动性的网页的新技术感到兴奋。使用 WebGL 制作 3D 图形吗?当然可以。WebAudio 的高级音频功能?没关系。要使用网络摄像头和麦克风进行实时协作应用程序吗?我要注册!
一些技术虽然不那么令人兴奋,但也同样重要,正是有了这些技术,我们能够更高效运行、更出色地改善整体用户体验。这正是 PageVisibility 等 API 的用武之地。
Page Visibility API 执行一项简单但重要的功能,它让您的应用知道网页何时对用户可见。通过这项基本信息,您可以制作在用户未查看时行为方式会有所不同的网页。请参考以下示例:
- 从服务器检索信息的网页在未被主动查看时可能会拖慢其更新周期
- 展示轮播图片或视频/音频内容的网页可能会暂停,直到用户再次显示该网页
- 应用可以决定仅当通知在视图中隐藏时才向用户显示通知
乍看之下,除了用户便利之外,此 API 似乎没什么用处,但考虑到移动网络浏览量的迅猛增长,任何有助于节省设备电池电量的措施都变得非常重要。通过使用 PageVisibility API,您的网站可以帮助用户的设备消耗更少的电量并延长使用寿命。
该 API 规范在撰写本文时处于“候选建议”阶段,它既提供了用于检测文档的可见性状态的属性,又提供了用于响应可见性变更的事件。
在本教程中,我将介绍 API 的基础知识,并展示如何将其应用到一些实际示例中(如果您缺乏耐心,可以跳过这些示例)。
文档公开范围属性
当前版本的 PageVisibilityAPI 规范定义了两个文档属性:布尔值 hidden
和枚举 visibilityState
。visibilityState 属性目前有四个可能的值:hidden
、visible
、prerender
和 unloaded
。
正如您所预期的,当文档完全不可见时,隐藏属性会返回 true。通常情况下,这意味着文档会最小化、在背景标签页上显示、操作系统的锁定屏幕打开,等等。如果文档的任何部分至少在一个显示屏上至少部分可见,则此属性设置为 false。此外,为了适应无障碍工具,当屏幕放大镜等工具会完全遮盖文档,但显示的是文档的视图时,可以将隐藏属性设置为 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 应用,请参阅其他与性能相关的文章。