检测网页退出的方法

背景

最近接了个需求,需要在用户非正常的退出我们业务流程的时候弹窗收集点信息。要求不高,就是用户点返回键退出到流程首页的时候弹窗。本以为很快的就能实现,没想到遇到了点坑,所以记录下实现的过程。

检测网页关闭的api

一开始我记得有个检测网页退出的事件,想着能不能通过监听这个事件来实现这个功能。查了下是onunloadmdn事件,发现这玩意儿不好用,一是不能自定义弹窗,
二是还有个巨丑的标题。没得办法,只能找其他方法了。

路由事件

后来网上搜到一个方案,浏览器的后退键可以触发popState事件,可以在页面打开的时候push一个state,在用户后退的时候通过监听popState和url来实现在首页监听用户点击返回键的功能。不得不说,网上的鬼才多,总能玩出点花样来。有了方案就撸个demo出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="max-age=0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
test
</body>
<script>
window.history.pushState(null, "测试", '#listen')
window.addEventListener('popstate', (e) =>{
console.log(e)
})
</script>
</html>

在浏览器中跑起来并没有输出任何内容。反复检查了代码,没有毛病、后来观察到不仅事件没生效,而且我们添加的history都没有生效,浏览器后退直接忽略的这个记录。怀疑是不是chrome做了优化,防止流氓的,一查还真是。页面打开的时候用js自动添加的记录会被忽略。需要用户手动操作才行。那加个按钮试试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="max-age=0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button type="button">测试</button>
test
</body>
<script>
const btn = document.querySelector('button')
btn.onclick = () => {
window.history.pushState(null, "测试", '#listen')
}
window.addEventListener('popstate', (e) =>{
console.log(location.href)
})
</script>
</html>

点击按钮后,点击回退键,能够正常输出url。在移动端也生效,微信环境中也行。基本解决问题了。

吐槽

虽然和这和文章没关系但是还是想吐槽下。现在web功能越来越强,但是web环境真的很糟糕,尤其国内一些厂商垄断后弄个阉割的浏览器。真的让人蛋疼。希望他们以后能做个人吧,不求创新,不阉割魔改就行。