如何使用JavaScript检测空闲的浏览器选项卡


Posted in Javascript onMay 28, 2020

在某些情况下,当用户与我们的最终产品或应用程序进行交互时,我们发现自己会执行许多密集的,占用大量CPU的任务。启动轮询器,建立WebSocket连接,甚至加载视频或图片等媒体,都有可能成为性能障碍,尤其是当这些任务在不需要的情况下消耗资源的时候。

在用户没有主动与界面交互的同时,从不必要的工作负载或网络请求中释放主线程是一个非常好的和有意义的实践。换一种方式,在大多数主机提供商都在引入基于配额的定价模式的行业中,减少网络请求也可以降低运行应用程序或服务的成本。

如何使用JavaScript检测空闲的浏览器选项卡

页面可见性(Page Visibility) API

所有现代的网页浏览器都加入了页面可见性API,它允许我们检测浏览器的标签页何时被隐藏,此外,我们还可以注册一个事件监听器,以检测可见性变化时的信号。

document.visibilityState

当页面处于前台时,document.visibilityState 可能是 visible ,最小化窗口的“标签”或隐藏。

我们可以通过以下方式直接访问 document.visibilityState:

console.log(document.visibilityState); 
// => 它可以是“visible”或“hidden”

visibilitychange Event

我们还可以使用事件侦听器轻松检测可见性属性中的更改。

const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  console.log('> 这个窗口是隐藏的.'); 
 } else { 
  console.log('> 这个窗口是可见的.'); 
 } 
}; 
document.addEventListener('visibilitychange', onVisibilityChange, false);

轮询示例

考虑一种情况,在这种情况下,我们正在轮询API以获取更新,并且希望避免对空闲用户进行不必要的调用。一个简化的示例如下所示:

const poll = () => { 
 const interval = 1500; 
 let _poller = null; 
 const repeat = () => { 
  console.log(`~ Polling: ${Date.now()}.`); 
 }; 
 
 return { 
  start: () => { 
   _poller = setInterval(repeat, interval); 
  }, 
  stop: () => { 
   console.log('~ Poller stopped.'); 
   clearInterval(_poller); 
  } 
 }; 
}; 
 
const poller = poll(); 
poller.start(); 
 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  poller.stop(); 
 } else { 
  poller.start(); 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

在后台异步加载

但有时我们可以通过反其道而行之,加速用户的终端体验。我们可以异步加载外部依赖或资产,而不是取消所有的作业和请求。这样,当用户回来时,他们的最终体验将更加“充实”并且丰富。

如何使用JavaScript检测空闲的浏览器选项卡

/ Webpack /

使用ES2015动态导入建议和适当的Webpack配置清单,我们可以轻松地在后台加载额外的模块或资产。

let loaded = false; 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  // Aggresively preload external assets ans scripts 
  if (loaded) { 
   return; 
  } 
  Promise.all([ 
   import('./async.js'), 
   import('./another-async.js'), 
   import(/* webpackChunkName: "bar-module" */ 'modules/bar'), 
   import(/* webpackPrefetch: 0 */ 'assets/images/foo.jpg') 
  ]).then(() => { 
   loaded = true; 
  }); 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

/ Rollup /

Rollup还支持开箱即用的动态导入。

let loaded = false; 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  // Aggresively preload external assets ans scripts 
  if (loaded) { 
   return; 
  } 
  Promise.all([ 
   import('./modules.js').then(({default: DefaultExport, NamedExport}) => { 
    // do something with modules. 
   }) 
  ]).then(() => { 
   loaded = true; 
  }); 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

/ 用Javascript预加载 /

除了使用捆绑器,我们还可以仅使用几行JavaScript来预加载静态资源(例如图像)。

let loaded = false; 
const preloadImgs = (...imgs) => { 
 const images = []; 
 imgs.map( 
  url => 
   new Promise((resolve, reject) => { 
    images[i] = new Image(); 
    images[i].src = url; 
    img.onload = () => resolve(); 
    img.onerror = () => reject(); 
   }) 
 ); 
}; 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  // Aggresively preload external assets ans scripts 
  if (loaded) { 
   return; 
  } 
  Promise.all( 
   preloadImgs( 
    'https://example.com/foo.jpg', 
    'https://example.com/qux.jpg', 
    'https://example.com/bar.jpg' 
   ) 
  ) 
   .then(() => { 
    loaded = true; 
   }) 
   .catch(() => { 
    console.log('> Snap.'); 
   }); 
 } 
}; 
document.addEventListener('visibilitychange', onVisibilityChange, false);

微互动

最后,一种吸引用户注意力的巧妙方法是动态更改图标,只需使用几个像素就可以保持交互。

const onVisibilityChange = () => { 
 const favicon = document.querySelector('[rel="shortcut icon"]'); 
 if (document.visibilityState === 'hidden') { 
  favicon.href = '/come-back.png'; 
 } else { 
  favicon.href = '/example.png'; 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

总结

到此这篇关于如何使用JavaScript检测空闲的浏览器选项卡的文章就介绍到这了,更多相关js浏览器选项卡内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Javascript Tab 导航插件 (23个)
Jun 11 Javascript
jquery实现弹出窗口效果的实例代码
Nov 28 Javascript
js动态创建标签示例代码
Jun 09 Javascript
js动态生成form 并用ajax方式提交的实现方法
Sep 09 Javascript
javascript实现的左右无缝滚动效果
Sep 19 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
Feb 21 Javascript
Angular 2.0+ 的数据绑定的实现示例
Aug 09 Javascript
删除table表格行的实例讲解
Sep 21 Javascript
JavaScript事件冒泡与事件捕获实例分析
Aug 01 Javascript
Egg.js 中 AJax 上传文件获取参数的方法
Oct 10 Javascript
jQuery利用cookie 实现本地收藏功能(不重复无需多次命名)
Nov 07 jQuery
详解node.js 事件循环
Jul 22 Javascript
js实现轮播图特效
May 28 #Javascript
JS写滑稽笑脸运动效果
May 28 #Javascript
Python版实现微信公众号扫码登陆
May 28 #Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
May 28 #Javascript
原生js实现五子棋游戏
May 28 #Javascript
Vue微信公众号网页分享的示例代码
May 28 #Javascript
纯JS实现五子棋游戏
May 28 #Javascript
You might like
PHP与SQL注入攻击防范小技巧
2011/09/16 PHP
php中邮箱地址正则表达式实现与详解
2012/04/24 PHP
PHP分页效率终结版(推荐)
2013/07/01 PHP
PHP大文件切割上传功能实例分析
2019/07/01 PHP
用JS控制回车事件的代码
2011/02/20 Javascript
关于js遍历表格的实例
2013/07/10 Javascript
jQuery简单实现banner图片切换
2014/01/02 Javascript
jQuery中document与window以及load与ready 区别详解
2014/12/29 Javascript
jQuery与getJson结合的用法实例
2015/08/07 Javascript
基于JavaScript实现动态创建表格和增加表格行数
2015/12/20 Javascript
基于jquery实现的仿优酷图片轮播特效代码
2016/01/13 Javascript
jQuery EasyUI框架中的Datagrid数据表格组件结构详解
2016/06/09 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
2016/07/27 Javascript
Bootstrap中表单控件状态(验证状态)
2016/08/04 Javascript
Javascript 判断两个IP是否在同一网段实例代码
2016/11/28 Javascript
基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析
2017/01/12 NodeJs
原生JS和jQuery操作DOM对比总结
2017/01/19 Javascript
利用jquery正则表达式在页面验证url网址输入是否正确
2017/04/04 jQuery
javascript基于牛顿迭代法实现求浮点数的平方根【递归原理】
2017/09/28 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
2018/08/29 Javascript
Python开发的单词频率统计工具wordsworth使用方法
2014/06/25 Python
安装ElasticSearch搜索工具并配置Python驱动的方法
2015/12/22 Python
python 把数据 json格式输出的实例代码
2016/10/31 Python
tensorflow之变量初始化(tf.Variable)使用详解
2020/02/06 Python
Python2及Python3如何实现兼容切换
2020/09/01 Python
Html5 canvas画图白板踩坑
2020/06/01 HTML / CSS
香港时装购物网站:ZALORA香港
2017/04/23 全球购物
COACH德国官方网站:纽约现代奢侈品牌,1941年
2018/06/09 全球购物
加拿大专业美发产品购物网站:Chatters
2021/02/28 全球购物
物理课外活动总结
2014/08/27 职场文书
2015大学生实训报告
2014/11/05 职场文书
2014年教师学期工作总结
2014/11/08 职场文书
教师岗位职责范本
2015/04/02 职场文书
工程技术负责人岗位职责
2015/04/13 职场文书
22句经典语录:送给优柔寡断和胡思乱想的朋友们
2019/12/13 职场文书
CocosCreator入门教程之网络通信
2021/04/16 Javascript