网页可见性

最近项目需要统计游戏在线时长,当数据量大的时候可以忽略一些特殊情况的数据(浏览器最小化、页面菜单切换、锁屏等)。但是在数据量少的情况下,需要把这些特殊情况排除掉,避免数据收到干扰。针对这种情况,浏览器有自带一种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、参考:

相关推荐
柚子科技几秒前
Vue3 响应式原理:我被 ref 和 reactive 坑了3次后终于搞懂了
前端·javascript·vue.js
五月君_7 分钟前
继 React、Vue 之后,Three.js 也有 Skills 了!AI 写 3D 终于不“晕”了
javascript·vue.js·人工智能·react.js·3d
scan72412 分钟前
大模型只是知道要调用工具,本身不
前端·javascript·html
摇滚侠33 分钟前
01 基础语法 JavaScript 入门到精通全套教程
开发语言·javascript·ecmascript
用户6919026813391 小时前
JS 初了解:从“网页玩具”到企业级语言的进化
javascript
月月大王的3D日记1 小时前
Three.js 材质篇(中):从兰伯特到PBR,一篇文章看懂五种光照材质
前端·javascript
且白1 小时前
leaflet切片变色、地图滤镜逻辑实现 colorfilter
前端·javascript
丷丩1 小时前
MapLibre GL JS第30课:添加视频
javascript·音视频·gis·mapbox·maplibre gl js
techdashen1 小时前
拆开任意 Electron 应用:从 Windows 安装包到 Discord 的私有更新协议
javascript·windows·electron
ZengLiangYi1 小时前
多格式文件解析:JSONL / SQLite / Event Stream
前端·javascript·后端