页面可见性改变事件 : visibilitychange 详解
1、Page Visibility API标准概述
查看W3C的官方文档时候看到这个属性 标准时间线是这样介绍的:
Page Visibility Level 2
W3C Proposed Recommendation 17 October 2017
查看W3C的工作流程的时候可以看到应该是处于W3C提议推荐的阶段,虽然还没有被完全的推荐成为标准,并且不是每一款浏览器都有所支持,但还是值得研究一下。
2、定义
顾名思义这是一个页面可见性API。
简单的说,浏览器标签页被隐藏或显示的时候会触发visibilitychange事件。
这是HTML5新提供的一个api,作用是记录当前标签页在浏览器中的激活状态。
所谓“激活状态”指当前标签是否正在被用户浏览。
我们知道,平时在PC端浏览网页的时候,使用的都是选项卡这种方式浏览网页,使用这种方式浏览,任何给定网页都有可能在后台,因此对用户不可见。页面可见性API提供了开发者可以观察的事件,以便了解文档何时可见或隐藏,以及查看页面当前可见性状态的功能。
页面可见性API对于节省资源和提到性能特别有用,它使页面在文档不可见时避免执行不必要的任务。
当用户最小化窗口或切换到另一个选项卡时,API会发送visibilitychange事件,让开发者知道页面状态已更改。你可以检测事件并执行某些操作或行为。例如,如果你的网络应用正在播放视频,则可以在用户将标签放入背景时暂停视频,并在用户返回标签时恢复播放。 用户不会在视频中丢失位置,视频的音轨不会干扰新前景选项卡中的音频,并且用户在此期间不会错过任何视频。这种体验是用户无感知的,并且对于用户体验是非常友好的。
因此规范的使用这个API可以减少对用户宽带的占用,减少服务器压力,节省用户内存,以及到达更好的播放效果。
3.罗列一些使用场景
1.网站有图片轮播效果,只有在用户观看轮播的时候,才会自动展示下一张幻灯片。
2.显示信息仪表盘的应用程序不希望在页面不可见时轮询服务器进行更新。
3.页面想要检测是否正在渲染,以便可以准确的计算网页浏览量(埋点使用场景)。
4.当设备进入待机模式时,网站想要关闭设备声音(用户按下电源键关闭屏幕)。
4. 该API的属性和事件
HTML5中专门为document元素添加了相关属性和事件:
属性:
1、
Document.hidden只读属性 布尔值 简单的表示标签页显示或者隐藏
如果页面处于被认为是对用户隐藏状态时返回true,否则返回false。
2、Document.visibilityState只读属性
是一个用来展示文档可见性状态的字符串,可能的值:
visible: 页面内容至少是部分可见。 在实际中,这意味着页面是非最小化窗口的前景选项卡。
hidden: 页面内容对用户不可见。 在实际中,这意味着文档可以是一个后台标签,或是最小化窗口的一部分,或是在操作系统锁屏激活的状态下。
prerender: 页面内容正在被预渲染且对用户是不可见的(被document.hidden当做隐藏). 文档可能初始状态为prerender,但绝不会从其它值转为该值。 注释:浏览器支持是可选的。
unloaded: 页面正在从内存中卸载。 注释:浏览器支持是可选的。
3、Document.onvisibilitychange
EventListener提供在visibilitychange事件被触发时要调用的代码。
5.应用实例场景:带有声音的视频
在此例中,当你切换到另一个标签时视频会暂停,当你返回到当前标签时视频会再次播放,代码如下:
<main>
<video id="videoElement" controls="" poster="thumbnail.jpg">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-Mobile.mp4" type="video/mp4" media="all and (max-width:680px)">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-Mobile.webm" type="video/webm" media="all and (max-width:680px)">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-SD.mp4" type="video/mp4">
<source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-SD.webm" type="video/webm">
<p>Sorry, there's a problem playing this video. Please try using a different browser.</p>
</video>
</main>
// 设置隐藏属性和改变可见属性的事件的名称
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
} var videoElement = document.getElementById("videoElement"); // 如果页面是隐藏状态,则暂停视频
// 如果页面是展示状态,则播放视频
function handleVisibilityChange() {
if (document[hidden]) {
videoElement.pause();
} else {
videoElement.play();
}
} // 如果浏览器不支持addEventListener 或 Page Visibility API 给出警告
if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else { // 处理页面可见属性的改变
document.addEventListener(visibilityChange, handleVisibilityChange, false); // 当视频暂停,设置title
// This shows the paused
videoElement.addEventListener("pause", function(){
document.title = 'Paused';
}, false); // 当视频播放,设置title
videoElement.addEventListener("play", function(){
document.title = 'Playing';
}, false);
}
6兼容性处理
为了支持老版本的浏览器,我们需要对document.hidden在做一些前缀处理:
function getHiddenProp(){
var prefixes = ['webkit','moz','ms','o'];
// 如果hidden 属性是原生支持的,我们就直接返回
if ('hidden' in document) {
return 'hidden';
}
// 其他的情况就循环现有的浏览器前缀,拼接我们所需要的属性
for (var i = 0; i < prefixes.length; i++){
// 如果当前的拼接的前缀在 document对象中存在 返回即可
if ((prefixes[i] + 'Hidden') in document) {
return prefixes[i] + 'Hidden';
}
}
// 其他的情况 直接返回null
return null;
}
同样的,我们可以获取document.visibilityState属性:
function getVisibilityState() {
var prefixes = ['webkit', 'moz', 'ms', 'o'];
if ('visibilityState' in document) {
return 'visibilityState';
}
for (var i = 0; i < prefixes.length; i++) {
if ((prefixes[i] + 'VisibilityState') in document){
return prefixes[i] + 'VisibilityState';
}
}
// 找不到返回 null
return null;
}
visibilitychange监听事件
你可以在document对象上注册一个监听visibilitychange事件,根据document.hidden或者document.visibilityState属性做一些业务逻辑:
var visProp = getHiddenProp();
if (visProp) {
// 有些浏览器也需要对这个事件加前缀以便识别。
var evtname = visProp.replace(/[H|h]idden/, '') + 'visibilitychange'; document.addEventListener(evtname, function () {
document.title = document[getVisibilityState()]+"状态";
},false);
}
上面的代码会在页面可见性发生变化时修改document.title的值
页面可见性改变事件 : visibilitychange 详解的更多相关文章
- HTML5事件—visibilitychange 页面可见性改变事件
转:https://blog.csdn.net/yusirxiaer/article/details/73480916 又看到一个很有意思的HTML5事件 visibilitychange事件是浏览器 ...
- jQuery 事件用法详解
jQuery 事件用法详解 目录 简介 实现原理 事件操作 绑定事件 解除事件 触发事件 事件委托 事件操作进阶 阻止默认事件 阻止事件传播 阻止事件向后执行 命名空间 自定义事件 事件队列 jque ...
- cocos2dx+lua注册事件函数详解 事件
coocs2dx 版本 3.1.1 registerScriptTouchHandler 注册触屏事件 registerScriptTapHandler ...
- 委托与事件代码详解与(Object sender,EventArgs e)详解
委托与事件代码详解 using System;using System.Collections.Generic;using System.Text; namespace @Delegate //自定义 ...
- cocos2dx+lua注册事件函数详解
coocs2dx 版本 3.1.1 registerScriptTouchHandler 注册触屏事件 registerScriptTapHandler 注册点击事件 registerScriptHa ...
- (转载)【cocos2dx 3.x Lua] 注册事件函数详解
出处: http://www.2cto.com/kf/201409/338235.html coocs2dx 版本 3.1.1 registerScriptTouchHandler 注册触屏事件 re ...
- 【转】关于cocos2dx+lua注册事件函数详解
转载:http://www.taikr.com/article/1605 registerScriptTouchHandler 注册触屏事件registerScriptTapHandler注册点击事件 ...
- 《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)
1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast,那么这个toast我们这边如何进行测试呢?今天宏哥就分两篇介绍一下. ...
- 《手把手教你》系列技巧篇(四十六)-java+ selenium自动化测试-web页面定位toast-下篇(详解教程)
1.简介 终于经过宏哥的不懈努力,偶然发现了一个toast的web页面,所以直接就用这个页面来夯实一下,上一篇学过的知识-处理toast元素. 2.安居客 事先声明啊,宏哥没有收他们的广告费啊,纯粹是 ...
随机推荐
- SQL 日期转换
), ): :57AMSELECT ), ): ), ): ), ): ), ): ), ): ), ): 06), ): ,06), ): ::46), ): :::827AMSELECT ), ) ...
- hdu 6065 RXD, tree and sequence
题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6065 (2017 Multi-University Training Contest - Team ...
- JS单线程和异步
线程和单线程的概念: 线程:是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同 ...
- python学习_新闻联播文字版爬虫(V 1.0版)
python3的爬虫练习,爬取的是新闻联播文字版网站 #!/usr/bin/env python # -*- coding: utf-8 -*- ''' __author__ = 'wyf349' _ ...
- learning armbian steps(10) ----- armbian 源码分析(五)
在上一节的分析当中,已经知道了uboot kernel的源代码路径及编译选项,以及rootfs的版本,相关信息如下所示: ## BUILD CONFIGURATION Build target: Bo ...
- VLC播放器:快捷键
造冰箱的大熊猫@cnblogs 2019/2/27 VLC播放器(VLC Media Player)快捷键汇总(在Ubuntu 16.04环境下测试) - 音量大/小:CTRL+上/下 - 静音开/ ...
- 『HGOI 20190917』Lefkaritika 题解 (DP)
题目概述 一个$n \times m$的整点集.其中$q$个点被m被设置为不能访问. 问这个点集中含有多少个不同的正方形,满足不包含任何一个不能访问的点. 对于$50\%$的数据满足$1 \leq n ...
- Spring——代理实现AOP
一.静态代理实现 1.接口(抽象主题) 2.接口的实现类(真实主题) 3.代理类(代理主题) 4.测试类: ApplicationContext context=new ClassPathXmlApp ...
- AcWing:172. 立体推箱子(bfs)
立体推箱子是一个风靡世界的小游戏. 游戏地图是一个N行M列的矩阵,每个位置可能是硬地(用”.”表示).易碎地面(用”E”表示).禁地(用”#”表示).起点(用”X”表示)或终点(用”O”表示). 你的 ...
- soa soap http rpc
soa 是一种计算机软件的设计模式,主要应用于不通应用组件中通过某种协议来互操作 它的基本设计原理是:服务提供了一个简单的接口,抽象了底层的复杂性,然后用户可以访问独立的服务,而不需要去了解服务底层平 ...