网页可见性

最近项目需要统计游戏在线时长,当数据量大的时候可以忽略一些特殊情况的数据(浏览器最小化、页面菜单切换、锁屏等)。但是在数据量少的情况下,需要把这些特殊情况排除掉,避免数据收到干扰。针对这种情况,浏览器有自带一种api,用来监听网页的可见性。本文针对这种情况,做个小测试。

1、Page Visibility API

  • Document.hidden:如果页面处于隐藏状态,则返回 true,否则返回 false
  • Document.visibilityState:
    • visible:页面内容至少部分可见
    • hidden:页面内容对用户不可见,原因可能是文档标签页在后台或属于最小化窗口的一部分,也可能是设备屏幕关闭。
  • visibilitychange:当标签页的内容变为可见或被隐藏时触发。

2、web页面生命周期

  • 获取当前页面生命周期状态
javascript 复制代码
    let eventName="visibilitychange",propName="hidden", stateName="visibilityState";
    ["webkit", "moz", "ms", "o"].every(m=>{
        if (typeof document[m+"Hidden"] !== 'undefined') {
            eventName = `${m}visibilitychange`;
            propName = `${m}Hidden`;
            stateName=`${m}VisibilityState`;
        }
    })
    const getState = () => {
            if (document[stateName] === 'hidden') {
                return 'hidden';
            }
            if (document.hasFocus()) {
                return 'active';
            }
            return 'passive';
    };

2、测试案例

javascript 复制代码
    let eventName="visibilitychange",propName="hidden", stateName="visibilityState";
    ["webkit", "moz", "ms", "o"].every(m=>{
        if (typeof document[m+"Hidden"] !== 'undefined') {
            eventName = `${m}visibilitychange`;
            propName = `${m}Hidden`;
            stateName=`${m}VisibilityState`;
        }
    })
    const getState = () => {
            if (document[stateName] === 'hidden') {
                return 'hidden';
            }
            if (document.hasFocus()) {
                return 'active';
            }
            return 'passive';
    };
    let timer = null; count = 0;
    document.addEventListener(eventName,()=>{
        if (document[propName]) {
            console.log("==>>隐藏");
            count=0;
            clearTimeout(timer);
        } else {
            console.log("==>>显示");
            loop("重新")
        }
        console.log(`==>>状态:${getState()}`);
    })
    const loop=(title)=>{
         timer=setTimeout(() => {
            count++;
            console.log(`==>>${title}定时任务:${count}`);
            console.log(`==>>状态:${getState()}`);
            loop(title);
        }, 3000)
    }

    loop("开始");
    window.addEventListener("blur",()=>{
        console.log("==>失去焦点");
    })

注意:如果当前页面仍是处于激活页面,就应该参考是否要通过全局添加事件监听,来判断用户是否有在操作,还是单纯挂机

3、使用场景

  • 暂停服务器接口轮询
  • 停止网页上动画、视频、音频等播放
  • 暂停游戏
  • 监控页面等

4、参考:

相关推荐
Maimai108084 小时前
React 项目目录结构怎么设计:从基础分层到真实业务落地
前端·javascript·react.js·microsoft·前端框架
开开心心就好4 小时前
带OCR识别的电子发票打印工具
运维·javascript·科技·游戏·青少年编程·ocr·powerpoint
之歆5 小时前
DAY_12JavaScript DOM 完全指南(三):高级工程篇
开发语言·前端·javascript·ecmascript
来恩10035 小时前
EL表达式应用
前端·javascript·vue.js
wh_xia_jun5 小时前
Vue3 + Vitest 浏览器测试 从零开发指南
前端·javascript·vue.js
唐青枫5 小时前
别再让 key 写成字符串:TypeScript keyof 从入门到实战
前端·javascript·typescript
天外飞雨道沧桑13 小时前
TypeScript 中 omit 和 record 用法
前端·javascript·typescript
暗冰ཏོ16 小时前
VUE面试题大全
前端·javascript·vue.js·面试
豹哥学前端19 小时前
事件循环(Event Loop)深度解析:让你彻底搞懂 JS 的执行顺序
前端·javascript·面试
竹林81819 小时前
用 wagmi v2 + Next.js 14 搞 NFT 交易市场前端:从合约调用失败到顺利上架,我踩了哪些坑
javascript·next.js