Page Visibility API

简介

有时候,开发者须要知道,用户正在离开页面。经常使用的方法是监听下面三个事件。javascript

  • pagehide
  • beforeunload
  • unload
    可是,这些事件在手机上可能不会触发,页面就直接关闭了。由于手机系统能够将一个进程直接转入后台,而后杀死。
  • 用户点击了一条系统通知,切换到另外一个 App。
  • 用户进入任务切换窗口,切换到另外一个 App。
  • 用户点击了 Home 按钮,切换回主屏幕。
  • 操做系统自动切换到另外一个 App(好比,收到一个电话)。
    上面这些状况,都会致使手机将浏览器进程切换到后台,而后为了节省资源,可能就会杀死浏览器进程。

之前,页面被系统切换,以及系统清除浏览器进程,是没法监听到的。开发者想要指定,任何一种页面卸载状况下都会执行的代码,也是没法作到的。为了解决这个问题,就诞生了 Page Visibility API。无论手机或桌面电脑,全部状况下,这个 API 都会监听到页面的可见性发生变化。java

这个新的 API 的意义在于,经过监听网页的可见性,能够预判网页的卸载,还能够用来节省资源,减缓电能的消耗。好比,一旦用户不看网页,下面这些网页行为都是能够暂停的。浏览器

  • 对服务器的轮询
  • 网页动画
  • 正在播放的音频或视频

document.visibilityState

这个 API 主要在document对象上,新增了一个document.visibilityState属性。该属性返回一个字符串,表示页面当前的可见性状态,共有三个可能的值。缓存

  • hidden:页面完全不可见。
  • visible:页面至少一部分可见。
  • prerender:页面即将或正在渲染,处于不可见状态。
    其中,hidden状态和visible状态是全部浏览器都必须支持的。prerender状态只在支持“预渲染”的浏览器上才会出现,好比 Chrome 浏览器就有预渲染功能,能够在用户不可见的状态下,预先把页面渲染出来,等到用户要浏览的时候,直接展现渲染好的网页。

只要页面可见,哪怕只露出一个角,document.visibilityState属性就返回visible。只有如下四种状况,才会返回hidden服务器

  • 浏览器最小化。
  • 浏览器没有最小化,可是当前页面切换成了背景页。
  • 浏览器将要卸载(unload)页面。
  • 操做系统触发锁屏屏幕。
    能够看到,上面四种场景涵盖了页面可能被卸载的全部状况。也就是说,页面卸载以前,document.visibilityState属性必定会变成hidden。事实上,这也是设计这个 API 的主要目的。

另外,早期版本的 API,这个属性还有第四个值unloaded,表示页面即将卸载,如今已经被废弃了。ide

注意,document.visibilityState属性只针对顶层窗口,内嵌的<iframe>页面的document.visibilityState属性由顶层窗口决定。使用 CSS 属性隐藏<iframe>页面(好比display: none;),并不会影响内嵌页面的可见性。函数

document.hidden

因为历史缘由,这个 API 还定义了document.hidden属性。该属性只读,返回一个布尔值,表示当前页面是否可见。动画

document.visibilityState属性返回visible时,document.hidden属性返回false;其余状况下,都返回truespa

该属性只是出于历史缘由而保留的,只要有可能,都应该使用document.visibilityState属性,而不是使用这个属性。操作系统

visibilitychange 事件

只要document.visibilityState属性发生变化,就会触发visibilitychange事件。所以,能够经过监听这个事件(经过document.addEventListener()方法或document.onvisibilitychange属性),跟踪页面可见性的变化。

document.addEventListener('visibilitychange', function () {
  // 用户离开了当前页面
  if (document.visibilityState === 'hidden') {
    document.title = '页面不可见';
  }
  // 用户打开或回到页面
  if (document.visibilityState === 'visible') {
    document.title = '页面可见';
  }
});

上面代码是 Page Visibility API 的最基本用法,能够监听可见性变化。

下面是另外一个例子,一旦页面不可见,就暂停视频播放。

var vidElem = document.getElementById('video-demo');
document.addEventListener('visibilitychange', startStopVideo);
function startStopVideo() {
  if (document.visibilityState === 'hidden') {
    vidElem.pause();
  } else if (document.visibilityState === 'visible') {
    vidElem.play();
  }
}

页面卸载

下面专门讨论一下,如何正确监听页面卸载。

页面卸载能够分红三种状况。

  • 页面可见时,用户关闭 Tab 页或浏览器窗口。
  • 页面可见时,用户在当前窗口前往另外一个页面。
  • 页面不可见时,用户或系统关闭浏览器窗口。
    这三种状况,都会触发visibilitychange事件。前两种状况,该事件在用户离开页面时触发;最后一种状况,该事件在页面从可见状态变为不可见状态时触发。

因而可知,visibilitychange事件比pagehidebeforeunloadunload事件更可靠,全部状况下都会触发(从visible变为hidden)。所以,能够只监听这个事件,运行页面卸载时须要运行的代码,不用监听后面那三个事件。

甚至能够这样说,unload事件在任何状况下都没必要监听,beforeunload事件只有一种适用场景,就是用户修改了表单,没有提交就离开当前页面。另外一方面,指定了这两个事件的监听函数,浏览器就不会缓存当前页面。

相关文章
相关标签/搜索