前言
最近做的项目里有一个新的需求,在不同的浏览器内打开的网页,监听用户的操作,比如关闭浏览器,刷新浏览器等等。
这就涉及到了几个平台:PC端浏览器,移动端IOS和安卓微信的webview等等。在微信里打开的H5网页,要获取到用户关闭页面的事件。经过对visibilitychange、 unload/pagehide 、onunload、popstate各种方法一阵测试,发现安卓里visibilitychange
能监听到关闭事件。而iOS里使用pagehide
能监听。
PC端
pc端的浏览器,比如谷歌 chrome、IE、360等等,都没有直接特定的监听关闭或者刷新的方法。所以这里采用时间差,来判断用户是刷新还是关闭,亲测可用:
//PC 端浏览器
let _beforeUnload_time = 0,_unload_time = 0
window.addEventListener('beforeunload', async ()=> {
_beforeUnload_time = new Date().getTime()
})
window.addEventListener('unload', async () => {
_unload_time = new Date().getTime()
//计算时间差
if (_unload_time - _beforeUnload_time <= 2) {
//用户关闭了页面
//此处关闭页面处理逻辑
alert("用户关闭了页面")
const data = await sendRequest({
url: `/destory`,
data: {gameId: gameId, userId: userid},
});
} else {
//用户刷新了页面
//此处刷新页面处理逻辑
alert("用户刷新了页面")
await checkEnqueue()
}
})
微信端
微信端为了考虑安全性,同样微信API也未给出一个特定的api接口调用,所以这里调用微信的第三方sdk:
1、引入微信sdk
<script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
2、判断是ios还是android
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
3、对不同的平台分别做相应的处理:
if (isAndroid) { //安卓
if (window.addEventListener) {
//安卓页面关闭
document.addEventListener("visibilitychange", async function () { //部分手机可以获取到
if (document.hidden) {
//用户关闭了安卓页面
//做关闭页面处理逻辑
await sendRequest({
url: `/destory`,
data: {gameId: gameId, userId: userid},
});
}
})
} else if (window.attachEvent) {
// 主要是为了兼容老的IE
window.attachEvent('onpagehide', async function () {
await sendRequest({
url: `/destory`,
data: {gameId: gameId, userId: userid},
});
})
} else {
window.onbeforeunload = async function () {
await sendRequest({
url: `/destory`,
data: {gameId: gameId, userId: userid},
});
}
}
} else if (isiOS){ //苹果
window.addEventListener("pagehide", function () {
let data = new Blob([JSON.stringify({gameId: gameId, userId: userid})], {
type: 'application/json; charset=UTF-8',
});
navigator.sendBeacon("/destory",data)
}, false);
window.addEventListener("pageshow", async function () {
await checkEnqueue();
});
}
注意:
ios 的 window.addEventListener("pagehide", function () {}
监听方法内,不支持 ajax
,需要通过
navigator.sendBeacon("url",data) 来调后台接口。