页面可见性改变事件 : 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.安居客 事先声明啊,宏哥没有收他们的广告费啊,纯粹是 ...
随机推荐
- 浮动float和清除clear
一.浮动(float) float简介 取值:left,right,none,inherit,默认none(不浮动) 可应用与所有元素 没有继承性 不在正常流中,但会影响布局.因为一个元素浮动时,其他 ...
- 2018 焦作网络赛 K Transport Ship ( 二进制优化 01 背包 )
题目链接 题意 : 给出若干个物品的数量和单个的重量.问你能不能刚好组成总重 S 分析 : 由于物品过多.想到二进制优化 其实这篇博客就是存个二进制优化的写法 关于二进制优化的详情.百度一下有更多资料 ...
- 28.Python list列表详解
在实际开发中,经常需要将一些(不只一个)数据暂储起来,以便将来使用.说到这里,一些读者可能知道或听说过数组,它就可以把多个数据挨个存储到一起,通过数组下标可以访问数组中的各个元素.但使用数组存储数据有 ...
- Java多线程核心知识(跳槽面试必备)
多线程相对于其他 Java 知识点来讲,有一定的学习门槛,并且了解起来比较费劲.在平时工作中如若使用不当会出现数据错乱.执行效率低(还不如单线程去运行)或者死锁程序挂掉等等问题,所以掌握了解多线程至关 ...
- Nginx-rtmp之配置项的管理
1. 概述 Nginx-rtmp 对 rtmp{...} 内的配置项划分了几个级别: 直接隶属于 rtmp{} 块内的配置项称为 main 配置项. 直接隶属于 server{} 块内的配置项称为 s ...
- leetcode-hard-array- 227. Basic Calculator II
mycode 29.58% class Solution(object): def calculate(self, s): """ :type s: str :rtyp ...
- C#产生随机验证码的代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- Linux 通道
简单地说,一个通道接受一个工具软件的输出,然后把那个输出输入到其它工具软件.使用UNIX/Linux的词汇,这个通道接受了一个过程的标准输出,并把这个标准的输出作为另一个过程的标准输入.如果你没有重新 ...
- javascript之for-in语句
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- ServletRequest与ServletResponse
http://lavasoft.blog.51cto.com/62575/275586/ 请求和相应是Web交互最基本的模式,在Servlet中,分别用HttpServletRequest与HttpS ...