前言
不知道大家平时有没有遇到过这样的需求
- 用户关闭浏览器或者刷新页面的时候,给用户一个提示,是否关闭浏览器或者刷新页面,如果用户点击了取消,那么就不进行操作,如果确定则进行操作。
- 刷新时不进行后续操作,关闭时需要给后台发送一个请求。
创建个普通的vue3项目
1 | npm init vite |
这里就不多说了,直接进入正题
监听浏览器关闭刷新事件
监听beforeunload即可,具体的可以查询官方文档
1 | window.addEventListener('beforeunload', function(event) { |
此时我们浏览器的效果就如下:
到这里,我们其实已经把直接关闭给拦截住了,然而我们需要操作并不是在提示出来的时候进行操作,因为点击取消的时候我们是不需要进行发送请求的,所以,我们的代码不可能写成这样
1 | window.addEventListener('beforeunload', function(event) { |
写一个nodejs服务
为了更好的观测是否发送了接口服务,我就先写了一个测试的node服务,大致步骤如下
- 新建一个文件夹里面创建index.js
- 使用vscode之类的打开,创建初始化包管理器,npm init -y
- 安装依赖express,这里大家可以使用自己喜欢的框架,比如koa之类的,我这里就用express了
- 书写index.js文件
- 这里nodejs的知识后续有机会再和大家分享,这里大家就看我写的代码就好了,这里的意思是我基于我本地创建了一个模拟数据,通过9527端口的服务就可以访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30const express = require('express')
const app = express()
// 模拟返回数据
const comebackData = [
{
name: 'jimson',
age: 18,
sex: '男'
},
{
name: 'licy',
age: 18,
sex: '女'
}
]
// 定义接口
app.get('/test', (req, res) => {
res.status(200)
console.log("我执行了")
res.json(comebackData)
})
// 配置服务
const server = app.listen(9527, () => {
const host = server.address().address
const port = server.address().port
console.log("This app listen at http://%s:%s", host, port)
})
- 启动服务,node index.js
此时我们去访问我们的get请求就可以得到我们的数据了
排除取消的情况
我们排除取消,当然就不可能在beforeunload
发送我们的请求了,这时候可以留意一下另外一个apiunload
,这是他的官网地址
这个api能让我们在页面刷新关闭的时候调用
1 | window.addEventListener('beforeunload', function(event) { |
此时我们的效果就是这样的:
这时候我们就实现了我们的需求了,但是这里有个问题就是需求处理失败了会怎么样,我们就不考虑了,一句话,拦不住~
知识拓展
刷新发送请求
如果我们刷新页面的时候也想要去调用这个请求呢,就是页面第一次进来不需要,后续就需要了
这里就有很多种方式了:
第一种就是
unload
的时候也去调用,其实我们unload
其实执行了,只是因为刷新导致页面重载了,请求被打断了,这时候我们给fetch
加一个keepalive
就可以保证接口发送出去1
2
3
4
5
6
7
8
9window.addEventListener('beforeunload', function(event) {
// 拦截关闭事件
event.preventDefault();
event.returnValue = '';
});
window.addEventListener('unload', function() {
fetch('http://192.168.1.52:9527/test',{keepalive:true})
})这样也就让刷新的时候也成功调用接口了
另外一种思路就是判断是否是第一次进入页面的方法了,这里有很多
第一种就是:window.performance.navigation.type == 1
,官方文档,
现在已经改成了PerformanceNavigationTiming
,官方文档
判断是刷新还是关闭
这里如果没用
1 | window.addEventListener('beforeunload', function(event) { |
代码进行拦截的话,我们可以使用时间差来判断
在beforeunload
定义一个当前时间Date now()
,然后在unload
里面定义一个Date now()
,两个时间相减,如果小于5ms,就是关闭,不然就是刷新,就是这俩个api执行时间差比较小那就是关闭,时间差比较大就是刷新。
页面tab切换api
这里还有个api可以让我们知道用户是不是切换了tab,这个api就是visibilitychange
,官方文档,这个就不展开说了,感兴趣的小伙伴可以自己去看看
结语
今天文章就分享到这里了,更多内容敬请期待~