前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >妙趣横生的HTML5 Page Visibility API

妙趣横生的HTML5 Page Visibility API

作者头像
Jeff
发布2018-01-22 10:39:17
9040
发布2018-01-22 10:39:17
举报
文章被收录于专栏:DeveWorkDeveWork

最近浏览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.visibilityStatedocument.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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015/03/26,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 深入解析Page Visibility API
  • Page Visibility API使用方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档