前端监听浏览器的关闭和刷新事件

8,320 阅读2分钟

监听浏览器相关事件, 判断浏览器关闭和刷新事件,并上报数据到服务器


浏览器关闭或刷新相关事件

# 浏览器关闭前
document.addEventListener("beforeUnload", () => {});

# 浏览器关闭,隐藏和tab切换
document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "hidden") {
  } else {
  }
});

# 浏览器关闭
document.addEventListener("unload", () => {});

用户操作行为

  • 用户关闭浏览器时事件执行顺序

    beforeUnload > unload

  • 用户刷新操作事件执行顺序

    beforeUnload > visibilityState(hidden) > unload

通过用户操作浏览器打印日志发现

  • 用户手动关闭浏览器时beforeUnload和unload事件执行的时间差保持在1毫秒

  • 用户刷新浏览器时beforeUnload和unload事件执行的时间差大概是保持在5-9毫秒之间,visibilityState事件几乎与unload同时执行(可能会比unload先执行一秒),最后执行的是unload事件

分析场景后我们可以通过事件触发的时间差来判断用户的操作行为,代码如下

let before_unload_time = 0
document.addEventListener("beforeUnload", () => {
  before_unload_time = new Date().getTime()
});
document.addEventListener("unload", () => {
  // 如果时间差大于等于5毫秒
  if(new Date().getTime() - before_unload_time >= 5) {
    console.log('用户刷新界面')
  } else {
    console.log('用户关闭界面')
  }
});

用户数据上报

正常情况上页面上报数据,直接调用接口即可,但是在用户刷新或关闭浏览器时,用普通的http请求大概率会出现数据上报不成功,这个时候可使用浏览器提供的sendBeacon方式实现

const url = 'https://canpointtest.com/frontEnd/dataApi/insertRecord'
const data = {
  type: 'send',
  name: '数据上报'
}
const blob = new Blob([JSON.stringify(data)], {
  type: 'application/json; charset=UTF-8',
})
navigator.sendBeacon(url, blob)

手机端与pc端浏览器区别

  1. 由于移动端浏览器与pc端不一样,没有关闭浏览器或浏览器标签的操作,移动端关闭浏览器相当于直接杀死程序,可能由于安全因素,我们是无法监听客户端杀死进程的操作的

  2. 在移动端关闭浏览器(杀死浏览器)事件中,在beforeUnload,unload, visibilitychange中执行上报失败,回到桌面时可以监听visibilitychange事件