最近项目需要统计游戏在线时长,当数据量大的时候可以忽略一些特殊情况的数据(浏览器最小化、页面菜单切换、锁屏等)。但是在数据量少的情况下,需要把这些特殊情况排除掉,避免数据收到干扰。针对这种情况,浏览器有自带一种api,用来监听网页的可见性。本文针对这种情况,做个小测试。
1、Page Visibility API
Document.hidden
:如果页面处于隐藏状态,则返回true
,否则返回false
。Document.visibilityState
: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、使用场景
- 暂停服务器接口轮询
- 停止网页上动画、视频、音频等播放
- 暂停游戏
- 监控页面等