一、功能需求
项目是企业微信内打开的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;
},}