visibilitychange监听页面可见性改变事件

参考文章1
参考文章2
参考文章3

一、功能需求

项目是企业微信内打开的webview页面,用户进入指定页面时,会调用企微提供的,持续监听用户位置变化的API,当用户将企微切后台一定时间后重新回到该页面,API监听不生效(方法并未销毁,只是不生效),查询官方文档,该企微API不支持后台监听,切后台就会被打断,故代码逻辑需改为,判断用户离开页面时,主动销毁该监听,判断用户进入页面时,重新创建监听,而判断用户是否离开或回到页面,可使用visibilitychange事件来判断页面的可见性。

二、visibilitychange事件

在H5中,文档对象(document对象)具有一个visibilityState属性,该属性表示当前文档对象的可见性状态,页面被隐藏或显示时,document.visibilityState属性就会发生变化,继而触发visibilitychange事件

visibilityState属性可能的取值:

  • visible 当前页面是非最小化窗口的屏幕最上层的页面

  • hidden 当前页面不可见处于后台或被最小化

  • prerender 当前页面处于预渲染状态,不可见

  • unloaded 当前页面正被销毁

简单范例:

javascript 复制代码
document.addEventListener('visibilitychange', function () {
  // 用户离开当前页面
  if (document.visibilityState === 'hidden') {
    document.title = '页面不可见';
  }

  // 用户打开或回到页面
  if (document.visibilityState === 'visible') {
    document.title = '页面可见';
  }
});

三、项目代码实例

javascript 复制代码
mounted(){
	this.bindEvent()
},
methods:{
	bindEvent(){
      // 开启监听页面是否可见事件
      const _this = this;
      // 判断当前浏览器支持何种类型的hidden
      let visProp = this.getHiddenProp();
      console.log('visProp-',visProp);
      if (visProp && typeof document.addEventListener !== 'undefined') {
        console.log('可设置监听事件');
        // 部分浏览器也需要对这个事件加前缀以便识别。
        let evtname = visProp.replace(/[H|h]idden/, '') + 'visibilitychange';
        document.addEventListener(evtname, handleVisibilityChange, false);
        _this.$once("hook:beforeDestroy",()=>{
          console.log('销毁监听事件')
          document.removeEventListener(evtname, handleVisibilityChange)
        })
      }else{
        console.error('当前浏览器不兼容!')
      }
      // 页面可见性变化时的回调函数
      async function handleVisibilityChange(){
        console.log('document.visibilityState-', document.visibilityState);
        if (document.visibilityState == "hidden") {
          try{
            await stopGetCoordinateLongTime();// 息屏时主动关闭持续监听位置变化
          }catch(e){
            console.error('息屏时关闭持续定位/罗盘有点问题,' + err);
          }
        } else{
          // 开启持续监听获取定位
          _this.getPositionByEnvi();
        }
      }
      
    },
    // 兼容性判断,判断当前浏览器支持何种类型的hidden
    getHiddenProp(){
      let prefixes = ['webkit','moz','ms','o'];
      // 如果hidden 属性是原生支持的,我们就直接返回
      if ('hidden' in document) 
        return 'hidden';
      
      // 其他的情况就循环现有的浏览器前缀,拼接我们所需要的属性 
      for (let i = 0; i < prefixes.length; i++){
        // 如果当前的拼接的前缀在 document对象中存在 返回即可
        if ((prefixes[i] + 'Hidden') in document) {
          return prefixes[i] + 'Hidden';
        }  
      }
      // 其他的情况 直接返回null
      return null;
    },}
相关推荐
matlab_xiaowang1 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
前端摸鱼匠3 小时前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker3 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
Linsk5 小时前
Java和JavaScript的关系真是雷峰和雷峰塔的关系吗?
java·javascript·oracle
当时只道寻常5 小时前
浏览器文本复制到剪贴板:企业级最佳实践
javascript
Alice-YUE6 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
是上好佳佳佳呀8 小时前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记
莎士比亚的文学花园8 小时前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
01漫游者9 小时前
JavaScript函数与对象增强知识
开发语言·javascript·ecmascript
threelab10 小时前
Three.js 代码云效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能