妙趣横生的HTML5 Page Visibility API
最近浏览36kr 的网页的时候偶然发现一个有趣的情况:当浏览器Tab 处于非当前页的时候,36kr 的标题栏会自动换成可爱的大白字符形象。Jeff 在第一次看到的时候就知道这种效果是通过HTML5 的Page Visibility API 实现的(不是吹牛)。
直到现在我还没去查看36kr 的源代码看其是如何实现的(也不打算去一个个查看它繁杂的js 文件了),HTML5 的Page Visibility API 以前看过,看到36kr 实现了这个的时候一时兴起,遂去查看文档深入了解之。然后三两下在自己的博客上实现了类似的效果(你可以切换Tab 到背后看看):
深入解析Page Visibility API
自从腾讯面试二面后,深深意识到“不去刨根问底的工程师跟搬砖的没啥区别”;虽然我一直认为好的技术文不应该过多复制API 文档的内容,但在这里还是从自己的角度为没接触过这个Page Visibility API 的同志们解析下。
荒芜年代一统天下的IE6 早已成为过去时(也许你还记得以前用IE6的时候每打开一个页面就弹出一个新的窗口,层层叠叠),现代浏览器在多Tab (标签后窗口)的构建形式上基本达成了共识,通常而言我们都是打开新标签页,在当前浏览器窗口中,每次都只有一个标签页处于激活态(或者说高亮),其余均为隐藏态。HTML5 的那帮搞标准的也适时提出了这个Page Visibility API——以期更好地利用这个“时隐时现”的动作。
在这里我们先稍微离题下,可能你知道,Chrome 浏览器较一般浏览器能更好稳定运行的原因在于其引入了沙盒机制,每个新建的标签页甚至是每个扩展都是独立在一个沙盒运行的。但如此一来带来的是系统资源的占用(Chrome 因耗内存被诟病就是如此来源于此)。回到正文,浏览器中每个标签页无论是激活态还是隐藏态,运作机制模式基本没啥区别的,原来该计算的还是在计算,原来在放视频的还是在放视频,占内存的还是在占内存。
但引入了Page Visibility API ,开发者可以做一些事情,让我们设想下面的场景并提供相应的demo:
场景一:视频网站用户在看视频时候切换到另外一个标签页了,视频自动暂停(点击查看Demo);
场景二:一些耗性能的页面在标签页处于隐藏状态时候自动停止相关运算,节省资源(点击查看Demo,援引自alloyteam);
场景三:好玩的,比如类似36kr 或本站的效果(点击查看Demo)。
场景N:桌面提醒Notification 开启隐藏态免打扰模式、流式加载的新闻页面在处于隐藏态时偷偷加载最新内容……
基本上,有了这个API,制约你的就是你的idea,你的想象力了。
Page Visibility API使用方法
Page Visibility API 有两个相关的属性:document.visibilityState
及document.hidden
。
document.visibilityState
有如下四个值:
hidden:当浏览器最小化、切换tab(the page is on a background tab)、电脑锁屏时visibilityState值是hidden
visible:当浏览器顶级context(top level browsing context)的document至少显示在一个屏幕(screen)当中时,返回visible;当浏览器窗口没有最小化,但是浏览器被其他应用遮挡时,visibilityState值也是visible
prerender:文档加载离屏(is loaded off-screen)或者不可见时返回prerender,浏览器可选择性的支持这个属性(not all browsers will necessarily support it)
unloaded:当文档(document)将要被unload时返回unloaded,浏览器可选择性的支持这个属性
document.hidden
是个布尔值属性,标签页处于隐藏态则为false,反之激活态为true。
最核心的是通过绑定visibilitychange
事件来达到需求:
document.addEventListener('visibilitychange', function(event) { if (!document.hidden) { // The page is visible. } else { // The page is hidden. } }); |
---|
因为兼容性的原因需要为相关函数添加不同的浏览器前缀:
// Get Browser-Specifc Prefixfunction getBrowserPrefix() { // Check for the unprefixed property. if ('hidden' in document) { return null; } // All the possible prefixes. var browserPrefixes = ['moz', 'ms', 'o', 'webkit']; for (var i = 0; i < browserPrefixes.length; i++) { var prefix = browserPrefixes[i] + 'Hidden'; if (prefix in document) { return browserPrefixes[i]; } } // The API is not supported in browser. return null; } // Get Browser Specific Hidden Propertyfunction hiddenProperty(prefix) { if (prefix) { return prefix + 'Hidden'; } else { return 'hidden'; }} // Get Browser Specific Visibility Statefunction visibilityState(prefix) { if (prefix) { return prefix + 'VisibilityState'; } else { return 'visibilityState'; }} // Get Browser Specific Eventfunction visibilityEvent(prefix) { if (prefix) { return prefix + 'visibilitychange'; } else { return 'visibilitychange'; }} |
---|
更多使用方法请查看上面的Demo 中的源代码。
=========
3.27 更新:写完后才发现介绍该API的中文文章已经是满大街了,唉又浪费我宝贵的时间了,下次提笔想写之前还是看看有没有人已经写过类似的文章吧。
部分参考来源:
https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API
http://www.alloyteam.com/2012/11/page-visibility-api/
http://code.tutsplus.com/articles/html5-page-visibility-api--cms-22021
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例