|
2 | 2 |
|
3 | 3 | ## 简介 |
4 | 4 |
|
5 | | -通常,开发者监听下面三个事件,判断用户是否离开当前页面。 |
| 5 | +有时候,开发者需要知道,用户正在离开页面。常用的方法是监听下面三个事件。 |
6 | 6 |
|
7 | 7 | > - `pagehide` |
8 | 8 | > - `beforeunload` |
9 | 9 | > - `unload` |
10 | 10 |
|
11 | | -问题是,手机上这些事件可能不会发生,页面就直接关闭了。因为手机可能会直接清除浏览器进程,从而导致这些事件不会触发。 |
| 11 | +但是,这些事件在手机上可能不会触发,页面就直接关闭了。因为手机系统可以将一个进程直接转入后台,然后杀死。 |
12 | 12 |
|
13 | 13 | > - 用户点击了一条系统通知,切换到另一个 App。 |
14 | 14 | > - 用户进入任务切换窗口,切换到另一个 App。 |
15 | 15 | > - 用户点击了 Home 按钮,切换回主屏幕。 |
16 | 16 | > - 操作系统自动切换到另一个 App(比如,收到一个电话)。 |
17 | 17 |
|
18 | | -上面这些情况,都会导致浏览器进程切换到后台,为了节省资源,手机可能就会自动终止一些后台进程。 |
| 18 | +上面这些情况,都会导致手机将浏览器进程切换到后台,然后为了节省资源,可能就会杀死浏览器进程。 |
19 | 19 |
|
20 | | -传统方法无法监听到页面被系统切换,或者系统清除浏览器进程。为了解决这个问题,Page Visibility API 就诞生了。不管是手机或桌面电脑,所有情况下,这个 API 都会监听到页面的可见性发生变化。 |
| 20 | +以前,页面被系统切换,以及系统清除浏览器进程,是无法监听到的。开发者想要指定,任何一种页面卸载情况下都会执行的代码,也是无法做到的。为了解决这个问题,就诞生了 Page Visibility API。不管手机或桌面电脑,所有情况下,这个 API 都会监听到页面的可见性发生变化。 |
21 | 21 |
|
22 | | -除了判断网页卸载,监听网页的可见性,还可以用来暂停或终止下面这些网页行为,以便节省资源,减缓电能的消耗。 |
| 22 | +这个新的 API 的意义在于,通过监听网页的可见性,可以预判网页的卸载,还可以用来节省资源,减缓电能的消耗。比如,一旦用户不看网页,下面这些网页行为都是可以暂停的。 |
23 | 23 |
|
24 | 24 | - 对服务器的轮询 |
25 | 25 | - 网页动画 |
26 | 26 | - 正在播放的音频或视频 |
27 | 27 |
|
28 | 28 | ## document.visibilityState |
29 | 29 |
|
30 | | -这个 API 主要在`document`对象上,新增了一个`document.visibilityState`属性。该属性返回一个字符串,表示页面当前的可见性,共有三个可能的值。 |
| 30 | +这个 API 主要在`document`对象上,新增了一个`document.visibilityState`属性。该属性返回一个字符串,表示页面当前的可见性状态,共有三个可能的值。 |
31 | 31 |
|
32 | 32 | > - `hidden`:页面彻底不可见。 |
33 | | -> - `visible`:页面完全可见,或一部分可见。 |
| 33 | +> - `visible`:页面至少一部分可见。 |
34 | 34 | > - `prerender`:页面即将或正在渲染,处于不可见状态。 |
35 | 35 |
|
36 | 36 | 其中,`hidden`状态和`visible`状态是所有浏览器都必须支持的。`prerender`状态只在支持“预渲染”的浏览器上才会出现,比如 Chrome 浏览器就有预渲染功能,可以在用户不可见的状态下,预先把页面渲染出来,等到用户要浏览的时候,直接展示渲染好的网页。 |
37 | 37 |
|
38 | 38 | 只要页面可见,哪怕只露出一个角,`document.visibilityState`属性就返回`visible`。只有以下四种情况,才会返回`hidden`。 |
39 | 39 |
|
40 | 40 | > - 浏览器最小化。 |
41 | | -> - 浏览器没有最小化,但是页面切换成了背景页。 |
| 41 | +> - 浏览器没有最小化,但是当前页面切换成了背景页。 |
42 | 42 | > - 浏览器将要卸载(unload)页面。 |
43 | 43 | > - 操作系统触发锁屏屏幕。 |
44 | 44 |
|
|
64 | 64 | document.addEventListener('visibilitychange', function () { |
65 | 65 | // 用户离开了当前页面 |
66 | 66 | if (document.visibilityState === 'hidden') { |
67 | | - document.title = '页面不可见'; |
| 67 | + document.title = '页面不可见'; |
68 | 68 | } |
69 | 69 |
|
70 | 70 | // 用户打开或回到页面 |
@@ -103,7 +103,9 @@ function startStopVideo() { |
103 | 103 |
|
104 | 104 | 这三种情况,都会触发`visibilitychange`事件。前两种情况,该事件在用户离开页面时触发;最后一种情况,该事件在页面从可见状态变为不可见状态时触发。 |
105 | 105 |
|
106 | | -由此可见,`visibilitychange`事件比`pagehide`、`beforeunload`、`unload`事件更可靠,所有情况下都会触发(从`visible`变为`hidden`)。因此,可以只监听这个事件,运行页面卸载时需要运行的代码,不用监听后面那三个事件。甚至可以这样说,`unload`和`beforeunload`事件在任何情况下都不必监听。 |
| 106 | +由此可见,`visibilitychange`事件比`pagehide`、`beforeunload`、`unload`事件更可靠,所有情况下都会触发(从`visible`变为`hidden`)。因此,可以只监听这个事件,运行页面卸载时需要运行的代码,不用监听后面那三个事件。 |
| 107 | + |
| 108 | +甚至可以这样说,`unload`事件在任何情况下都不必监听,`beforeunload`事件只有一种适用场景,就是用户修改了表单,没有提交就离开当前页面。另一方面,指定了这两个事件的监听函数,浏览器就不会缓存当前页面。 |
107 | 109 |
|
108 | 110 | ## 参考链接 |
109 | 111 |
|
|
0 commit comments