Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Page Visibility API 教程

Page Visibility API 教程

作者头像
ruanyf
发布于 2018-11-22 03:32:50
发布于 2018-11-22 03:32:50
66200
代码可运行
举报
运行总次数:0
代码可运行

一、简介

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

  • pagehide
  • beforeunload
  • unload

但是,这些事件在手机上可能不会触发,页面就直接关闭了。因为手机系统可以将一个进程直接转入后台,然后杀死。

  • 用户点击了一条系统通知,切换到另一个 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属性),跟踪页面可见性的变化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
document.addEventListener('visibilitychange', function () {
  // 用户离开了当前页面
  if (document.visibilityState === 'hidden') {
    document.title = '页面不可见';
  }

  // 用户打开或回到页面
  if (document.visibilityState === 'visible') {
    document.title = '页面可见';
  }
});

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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事件只有一种适用场景,就是用户修改了表单,没有提交就离开当前页面。另一方面,指定了这两个事件的监听函数,浏览器就不会缓存当前页面。

六、参考链接

  • Page Visibility Level 2, W3C
  • Page Visibility API, David Walsh
  • Using the pageVisbility API, Joe Marini
  • Using PC Hardware more efficiently in HTML5: New Web Performance APIs, Part 2, Jatinder Mann
  • Don't lose user and app state, use Page Visibility, Ilya Grigorik

(完)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年10月25日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle 基于 RMAN 的不完全恢复(incomplete recovery by RMAN)
      Oracle 数据库可以实现数据库不完全恢复与完全恢复。完全恢复是将数据库恢复到最新时刻,也就是无损恢复,保证数据库无丢失的恢复。而不完全恢复则是根据需要特意将数据库恢复到某个过去的特定时间点或特定的SCN以及特定的Sequence。我们可以通过基于用户管理的不完全恢复实现,也可以通过基于RMAN方式来实现。本文主要描述是基于RMAN的不完全恢复的几种情形并给出示例。有关数据库备份恢复,RMAN备份恢复的概念与实战可以参考文章尾部给出的链接。
Leshami
2018/08/13
2.6K0
下载丨9月数据库技术通讯:Redo日志丢失,重建遭遇ORA-16433处理
在Oracle中,Redo日志文件包含所有的数据库变化历史记录,例如所有的DML变化(INSERT、UPDATE、DELETE和SELECT FOR UPDATE)和所有DDL语句造成的数据字典对象的更改及递归语句的更改等,所以redo文件可以最大限度地保证数据的一致性与安全性。万一数据库出现故障可以启用数据恢复。但是redo日志被误删了怎么办呢?本文通过一个案例来了解一下redo日志被误删,强制开库遭遇ORA-16433,供大家参考。
数据和云
2020/10/09
4860
案例:记录一则强制开库遭遇ORA-16433的处理过程
客户的一套开发环境,大概了解到的背景是清理空间时redo被运维人员当作log误删除,一线同事先接手处理,过程中遇到问题升级到我这里继续分析。 接手后,数据库处于mount状态,之前恢复过程中已经做过resetlogs的操作,也设置了"_allow_resetlogs_corruption"隐藏参数为true,目前直接开库会提示需要恢复,重新进行resetlogs时报错ORA-600 [2662],起初看到这个错误心中略有些放松,根据经验,推下SCN就好了:
Alfred Zhao
2020/09/10
1.1K0
偷梁换柱 | 无备份情况下的数据恢复实践(二)
在数据恢复实践(一)中,我们了解到在 Windows 的11.2.0.1的环境中恢复过程比较顺利,那么接下来的测试,是我遇到更加复杂的情况:系统表空间保护两个不连续的系统文件;恢复过程中出现 ORA 错误及数据字典不匹配的情况。我借助了一些非常规的手段规避这些问题,达到数据拯救的目的。
数据和云01
2019/05/26
4650
Oracle数据库工程师手记:备份恢复双城记(一)
本文作者系大连健哥、 POSTGRESQL、ORACLE 数据库资深从业人员、IT 技术的深度爱好者。相信科学改变人类、技术创造未来。个人主页:https://www.cnblogs.com/gaojian/,经其本人授权发布。
SQLplusDB
2022/08/19
7800
备库跳归档恢复的有趣案例(r9笔记第19天)
在Data Guard环境中,主备库基本都是使用归档来传递数据的变化。如果主备的归档传输中断,同时主库的归档被删除或者损坏,这种情况下备库是没法开始继续接收归档,应用新的数据变更了。 看到网友paulyibin的文章中提到了SCN恢复的想法,感觉非常有意思,明白了思路,自己在本地也测试了一把,发现真是有趣。 一般来说,主库的归档丢失,常规的思路只能是重建备库了。其实我们可以换一个角度来看这个问题,数据的变化在归档中是一个连续的过程,而在日志文件,数据 文件中则是一个状态。我们可以
jeanron100
2018/03/19
6360
实战篇:Oracle DataGuard 出现 GAP 修复完整步骤
DG GAP 顾名思义就是:DG不同步,当备库不能接受到一个或多个主库的归档日志文件时候,就发生了 GAP。
Lucifer三思而后行
2022/01/08
4.1K0
实战篇:Oracle DataGuard 出现 GAP 修复完整步骤
Oracle 基于用户管理的不完全恢复
    Oracle 数据恢复从恢复类型来说,抛开具体的文件,总共可分为两大类型的恢复,一是完全恢复,一个是不完全恢复。其实,熟悉了Oracle 体系结构之后,对于Oracle恢复就会有一个总体的概念。因为Oracle组成的外围部分,主要由不同的文件来组成,每种不同类型的文件有不同的 作用,因此只要了解了其作用,更利于了解与掌握Oralce数据库的备份与恢复。言归正传,完全恢复即是把数据库恢复到最新的SCN,出故障前 的那一刻,是无损恢复。而不完全恢复即是有损恢复,多用于恢复用户误操作,归档日志丢失等情形。本文主要描述基于用户管理的不完全恢复。
Leshami
2018/08/14
6460
Oracle 控制文件(CONTROLFILE)
为二进制文件,初始化大小由CREATE DATABASE指定,可以使用RMAN备份
Leshami
2018/08/07
6690
偷梁换柱 | 无备份情况下的数据恢复实践
在实际环境中,许多数据库环境并没有做好完整的数据备份恢复计划及容灾方案,无法保证数据安全,并且出现一些灾难性的错误。那么我们就面临这样的问题:在什么样的最极端情况下,我们还能挽救回数据呢? 我们的用户数据存储在相应表空间的数据文件当中,而元数据部分则存储在系统表空间的数据文件当中。假如仅存在系统表空间及重要数据文件(而非所有数据文件)的情况下还有希望恢复数据吗?当然,这里不讨论使用 Dul 的方式进行恢复。 就这个问题,我做了两个测试,一个是在 Windows 的11.2.0.1的环境中,一个是在 Lin
数据和云
2018/03/29
6210
Oracle 12c系列(十) | 12c中的Recovering Tables and Table Partitions
在Oracle12c之前的版本中,rman进行数据恢复时只能进行database/tablespace/datafile/block四种级别的恢复,如果误操作删除某张表或表中数据,无法通过闪回进行数据还原时,且有完整备份以及归档,该种情况下可以进行表空间时间点恢复,但恢复方式较麻烦,在Oracle12c中,Oracle对rman功能进行了增强,除了之前的四种级别的恢复,rman也提供了表/表分区级别的恢复,该特性可以直接从现有的rman备份中来恢复表/表分区,且恢复的过程不影响数据库中的其他的对象。
沃趣科技
2018/08/20
9070
Oracle 12c系列(十) | 12c中的Recovering Tables and Table Partitions
Oracle数据库工程师手记:备份恢复双城记(二)
本文作者系大连健哥, POSTGRESQL、ORACLE 数据库资深从业人员、IT 技术的深度爱好者。相信科学改变人类、技术创造未来。个人主页:https://www.cnblogs.com/gaojian/,经其本人授权发布。
SQLplusDB
2022/08/19
4320
Oracle Recovery 02 - 常规恢复之不完全恢复
背景:这里提到的常规恢复指的是数据库有完备可用的RMAN物理备份。 实验环境:RHEL6.4 + Oracle 11.2.0.4 单实例.
Alfred Zhao
2019/05/24
1.2K0
Oracle12c修复GAP新方法
12c可以通过Server name直连主库,Online修复,省去Rman基于scn备份后再传输到备库恢复的冗繁步骤
杨漆
2021/07/25
8340
Oracle12c修复GAP新方法
恢复控制文件避免使用resetlogs选项 (r10笔记第12天)
在搭建Data Guard的时候,我们可以直接从主库生成一个备库控制文件,或者拷贝一个备库的控制文件即可,后续的工作就交给Data Guard来自动恢复完成了,尤其是使用rman备份恢复的时候,使用recover database是一气呵成,我们无须理会其中更多的细节,当然实际上Oracle已经帮我们处理好了。 我们都知道控制文件的备份有两种方式,一种是镜像,一种是trace。镜像备份方式类似alter database backup controlfile to 'xxxxx'这样的形式
jeanron100
2018/03/19
5810
DBA生存警示:保护现场不要让事情更糟
张乐奕 云和恩墨副总经理 Oracle ACE 总监 ITPUB Oracle数据库管理版版主、Oracle高可用版版主、ACOUG联合创始人 今天收到一个发过来请求帮助的 case,Oracle 数据库无法启动,请求帮助恢复。仔细阅读了发过来的告警日志,这是一个典型的“事情越弄越糟”的案例。 作为一个专业的DBA,在遇到问题时,一定要思考:如何保护现场,不让事情变得更糟。这是基本要求,保护现场以使得其他人接手工作时,可以从原有状态开始。 以下就来根据告警日志,一条一条地回顾这位 DBA 是如何将数据
数据和云
2018/03/06
1.2K0
DBA生存警示:保护现场不要让事情更糟
理解 using backup controlfile
        using backup controlfile 通常用于恢复由于当前控制文件丢失且原来备份的控制文件较当前发生变化的情形之下。using backup controlfile 的 recover 方式一旦使用之后,常用的recover database命令将不可再使用,且必须要使用resetlogs方式来打开数据库,下面是具体的演示描述。
Leshami
2018/08/14
5220
Oracle数据库恢复之resetlogs
首先要明确resetlogs操作非常危险的,也只有在进行不完全恢复开库时会使用到。
Alfred Zhao
2019/05/21
1.2K0
Oracle丢失的是所有的redo日志组
我做实验的过程中有一个诡异的情况,我先把redo文件从操作系统层面都删除了,但是数据库正常创建表,insert数据,我理解的是当你commit的时候,会触发lgwr进程从redo log buffer中涮新redo 到redo 文件中,但是redo文件已经被删除了,就会报错,但是他并没有报错:
星哥玩云
2022/08/18
3560
使用RMAN增量备份处理Dataguard因归档丢失造成的gap
Thu Mar 29 11:21:45 2018 FAL[client]: Failed to request gap sequence  GAP - thread 1 sequence 184-185  DBID 1484954774 branch 960494131 FAL[client]: All defined FAL servers have been attempted. ------------------------------------------------------------ Check that the CONTROL_FILE_RECORD_KEEP_TIME initialization parameter is defined to a value that's sufficiently large enough to maintain adequate log switch information to resolve archivelog gaps.
星哥玩云
2022/08/16
5470
推荐阅读
相关推荐
Oracle 基于 RMAN 的不完全恢复(incomplete recovery by RMAN)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验