一、简介
要知道用户何时离开,有常用的方法是监听下面三个事件。
pagehide
beforeunload
unload
可上述三种方法有一个bug就是,这些事件在手机上可能不会触发,页面就直接关闭了。因为手机系统可以将一个进程直接转入后台,然后杀死。
用户点击了一条系统通知,切换到另一个 App。
用户进入任务切换窗口,切换到另一个 App。
用户点击了 Home 按钮,切换回主屏幕。
操作系统自动切换到另一个 App(比如,收到一个电话)。
其实上面说的过程是可以实现监听,但会导致手机将浏览器进程切换到后台,这样手机会因为节省资源,极有可能就会杀死浏览器进程。
之前那无法监听是因为页面被系统切换,以及系统清除浏览器进程。现在我们换种解决思路,用Page Visibility API。不管手机或桌面电脑,所有情况下,这个 API 都会监听到页面的可见性发生变化。
这个新的 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,表示页面即将卸载,这也已经扔了。
注意,document.visibilityState属性只针对顶层窗口,内嵌的<iframe>页面的document.visibilityState属性由顶层窗口决定。
使用 CSS 属性隐藏<iframe>页面(比如display: none;),并不会影响内嵌页面的可见性。
三、document.hidden
由于历史原因,这个 API 还定义了document.hidden属性。该属性只读,返回一个布尔值,表示当前页面是否可见。
当document.visibilityState属性返回visible时,document.hidden属性返回false;其他情况下,都返回true。
该属性只是出于历史原因而保留的,只要有可能,都应该使用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事件比pagehide、beforeunload、unload事件更可靠,所有情况下都会触发(从visible变为hidden)。因此,可以只监听这个事件,运行页面卸载时需要运行的代码,不用监听后面那三个事件。
说完上面我们可以知道,其实unload事件在任何情况下都不必监听,beforeunload事件只有一种适用场景,就是用户修改了表单,没有提交就离开当前页面。另一方面,指定了这两个事件的监听函数,浏览器就不会缓存当前页面。
参考链接
Page Visibility Level 2, W3C
Page Visibility API, David Walsh
Using the pageVisbility API, Joe Marini
Don't lose user and app state, use Page Visibility, Ilya Grigorik
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/128191.html
摘要:大学,光学工程研究生毕业,和程序猿完全不搭边。那怎么办,试着学一学呗,学习才是程序猿的天性。所以我在想程序猿是不是都需要新知识刺激一下,才能保持兴奋的头脑。有句话说的很对程序猿就像好奇的猫,追着毛球的线头玩,最后一个毛球在脑袋里搅浆糊。 说说我自己的经历。211大学,光学工程研究生毕业,和程序猿完全不搭边。 毕业后进了成都某国字头研究所,在行业里摸爬滚打了四年,2018年机缘巧合在家养...
摘要:作品演示站源码地址本站鸣谢程序员翟永超以及主题大部分的前端博客页面都是使用的主题。下定决心做这个博客也是因为自己面临毕业,很多东西确实应该尝试。我想是写博客的必备技能吧。哈哈结语本篇主要简单介绍一下的基本情况,下一篇将对的部署和技术做总结。 转载请注明博客出处 http://www.eumji025.com/artic... 前言 一直都准备做一个博客系统,直到四月份才真正的...
摘要:你只需要花分钟,就能拥有一个属于自己的私人博客了,并且可以对整个项目有一个完成的概念和感觉。指令和相似,表达式和保持一致,易学易用。 本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和运行 Tale 项目。示例均在 Windows 操作系统下演示 showImg(https://segmentfault.com/img/bVbwsbo?w=1578&h=868); 本文作者:...
摘要:比如把上面画正方形的例子稍做变化重复执行次画正方形开始画正方形结束右转度执行后,可以看到,画出一个非常规整漂亮的组合图案。 turtle图形库源于1966年诞生的Logo语言,是入门Python的有趣工具。因其简单便捷的图形化方法、和立即反馈式的绘画效果,成为众多编程入门者的首选。相对于大多数入门教材中枯燥的语法学习,和函数、方法的演练来说,turtle的趣味性显得别具一格、极富效...
阅读 498·2023-03-27 18:33
阅读 705·2023-03-26 17:27
阅读 605·2023-03-26 17:14
阅读 575·2023-03-17 21:13
阅读 498·2023-03-17 08:28
阅读 1752·2023-02-27 22:32
阅读 1258·2023-02-27 22:27
阅读 2065·2023-01-20 08:28