亲测有效
背景:最近做一个倒计时记录学习时长项目,需要在用户点击浏览器的返回按钮或者直接关闭浏览器,或者直接退出微信或者进入后台时记录下当前页面的进度,下次进去从上次退出的地方开始倒计时。一开始想的很简单直接监测浏览器的返回事件window.onbeforeunload,在安卓和pc上可以监测到,但是iOS上监测不到
解决办法:根据百度相关文档,发现iOS端检测需要用pagehide去检测,于是修改代码如下
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isAndroid) {
//这个是安卓操作系统
window.onbeforeunload = function () {
//窗口关闭前
// ...暂停倒计时并且ajax请求记录到数据库
};
} else if (isIOS) {
//这个是ios操作系统
window.addEventListener('pagehide', function () {
// ...暂停倒计时并且ajax请求记录到数据库
});
} else {
//这个pc
window.onbeforeunload = function () {
//窗口关闭前
// ...暂停倒计时并且ajax请求记录到数据库
};
}
调试是打断点iOS还是无法监测到,当时郁闷了很长时间,苹果官方文档明明写了用这个能监测到,但是我居然监测不到,一度以为是系统版本低,升级到最新系统发现还是监测不到pagehide,无法记录数据到数据库,最后翻遍百度在一个帖子的不起眼的评论里看到了一句话说把ajax请求改成同步试试,我抱着试试的态度修改了代码
//这个是ios操作系统
window.addEventListener('pagehide', function () {
$.ajaxSetup({
async: false//关闭异步
});
// ...ajax请求记录数据到数据库
});
window.addEventListener('pageshow', function () {
$.ajaxSetup({
async: true//页面显示时恢复异步
});
});
发布测试居然监测到了,郁闷已久的问题终于解决了,虽然不知道什么原因,但是解决了就是好事
监测浏览器返回、关闭、退出、进入后台完整代码
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isAndroid) {
//这个是安卓操作系统
window.onbeforeunload = function () {
//窗口关闭前
// ...ajax操作
$.ajax({
url: ctx + "login/test",
type: 'get',
data: {},
async: true,
success: function (data) {
}
})
};
} else if (isIOS) {
//这个是ios操作系统
window.addEventListener('pagehide', function () {
$.ajaxSetup({
async: false
});
// ...ajax操作
$.ajax({
url: ctx + "login/test",
type: 'get',
data: {},
async: true,
success: function (data) {
}
})
});
window.addEventListener('pageshow', function () {
$.ajaxSetup({
async: true
});
});
} else {
//这个pc
window.onbeforeunload = function () {
//窗口关闭前
// ...ajax操作
$.ajax({
url: ctx + "login/test",
type: 'get',
data: {},
async: true,
success: function (data) {
}
})
};
}
window.addEventListener("popstate", function (e) {
// ...ajax操作
$.ajax({
url: ctx + "login/test",
type: 'get',
data: {},
async: true,
success: function (data) {
}
})
}, false);
if (typeof document.hidden !== "undefined") {
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
document.addEventListener(visibilityChange, function () {
console.log("当前页面是否被隐藏:" + document[hidden]);
if (document[hidden]) {//页面被隐藏,进入后台运行时监测
// ...ajax操作
$.ajax({
url: ctx + "login/test",
type: 'get',
data: {},
async: true,
success: function (data) {
}
})
}
else {
// ...页面重新进入前台时操作,比如恢复倒计时
}
}, false);
要使用异步请求,同步请求我测试时无法接收到,在测试中发现手机用微信初次打开第一个页面时直接点击左上角“×”无法接收到请求
在安卓和iOS微信浏览器监测页面关闭返回的方法,当时测试时是有效果的,后来在安卓端不起作用了,只有浏览器中没有页面缓存重新加载时,才有作用
初步判断是页面首次加载时window.onbeforeunload起作用了,下一次进入读取的缓存页面,window.onbeforeunload不起作用了
window.addEventListener('pagehide', function () {})在iOS上没有问题,但是在安卓上不管第一次进入还是从缓存读取都不起作用,应该是浏览器兼容问题
通过debugmm.qq.com/?forcex5=true或者debugstbs.qq.com开启微信浏览器为X5内核后,发现安卓端可以用了,window.addEventListener('pagehide', function () {})起作用了
debugmm.qq.com/?forcex5=false关闭X5内核后,又不起作用了
发现
window.addEventListener( 'blur', function() { console.log( 'blur' ); } );
window.addEventListener( 'focus', function() { console.log( 'focus' ); } );
可以检测点击了关闭浏览器的功能,但是返回监测不到
经过测试发现
window.onbeforeunload = function () {
//窗口关闭前
saveExam(that)
};能监测到返回
所以最后解决方式是在安卓里用
window.addEventListener( 'blur', function() { console.log( 'blur' ); } );结合window.onbeforeunload和 window.addEventListener("popstate", function (e) {
iOS里用pagehide
原文地址:https://www.cnblogs.com/stubborn-donkey/p/12851687.html