需求小能手——拦截浏览器窗口关闭

前言

最近碰到一个需求,网页端页面有评价功能,要求用户点击关闭浏览器时强制弹出评价对话框让用户评价。刚听到这个需求我大意了没有闪,以为很简单,没想到很难实现,很多需求果然不能想当然啊,接下来我们来看一下该功能实现的一些思路。

窗口关闭

要想实现该功能最简单的想法就是监听浏览器关闭事件,然后阻止默认事件,执行自定义的事件。整个思路核心就是监听事件,搜索一番果然有浏览器关闭触发的事件。

事件

  • onunload:资源被卸载时触发,浏览器窗口关闭时卸载资源就会触发,我们监听一下该事件看能不能阻止窗口关闭。
js 复制代码
    window.addEventListener('unload', function (e) {
      console.log(e);
      e.preventDefault()
    });

打开页面再关闭,会发现控制台打印出了e然后就关闭了,看来在onunload事件中并不能阻止窗口关闭,得另找方法,刚好在onunload事件介绍中还链接了一个事件------beforeonunlaod。

  • beforeunload :当窗口关闭或刷新 时触发,该事件在onunload之前触发。并且在该事件中可以弹出对话框,询问用户是否确认离开或者重新加载,这不是正是我们想要的效果。根据mdn上的介绍,要想出现弹出对话看需要用preventDefault()事件,并且为了兼容性我们最好再加上以下方法中的一个:
    1.将e.renturenValue赋一个字符串。
    2.事件函数返回一个字符串。 接下来让我们试一试:
js 复制代码
    window.addEventListener('beforeunload', function (e) {
      e.preventDefault()
      e.returnValue = ''
    });

打开关闭未生效,再检查下代码没问题呀,这是因为浏览器本身安全机制导致的,在ie浏览器中没有任何限制,但是在chrome、edge等浏览器中用户必须在短时间操作过页面 才能触发。打开页面点几个文字在关闭窗口,这次就能出现弹窗了。

当我们点击离开页面就会关闭,点击取消继续停留,上面提到过刷线也能触发,我们再点下刷新。

出现的提示有所改变,我们知道浏览器的刷新有好几种方式,我们可以都尝试一下:

  • ctrl+R:本身就是浏览器刷新按钮的快捷键,能够触发。
  • f5:能否触发。
  • 前进、后退:能够触发。
    这三种方式提示内容跟点击刷新按钮一样。回到我们的需求,虽然已经能够阻止窗口关闭,但是刷新依旧能阻止,我们需求是用户关闭,所以我们要区分用户操作是刷新还是关闭。

区分

要想区分就要找到以下两者之间的区别,两者都会执行onbeforeunload与onunload两个事件,不能直接通过某个事件区分。但是两个事件之间的时间差是不同的。刷新时两者时间差在10毫秒左右,而关闭时在3毫秒左右,判断以下时间差就能区分出来。

js 复制代码
       var time = null;
    window.addEventListener('beforeunload', function (e) {
      time = new Date().getTime();
    });
    window.addEventListener('unload', function (e) {
      const nowTime = new Date().getTime();
      if (nowTime - time < 5) {
        console.log('窗口关闭');
      }
    });

用此方法就能区分出来,但是此判断是在onunload事件中的,而窗口弹出是在beforeunlaod,这方法只适用于在关闭时执行某个函数,但不能满足我们的需求。除此之外还有一个问题就是刷新默认弹出对话框的内容是不能修改的,所以如果我们想要弹出自定义的对话框是不可能的。经过分析操作能够做到的就是,在用户刷新或关闭时出现系统自带对话框,同时在下方弹出自定义对话框,然后用户点击取消再去操作自定义对话框。

总结

总的来说要想拦截浏览器窗口关闭并且弹出自定义对话框,目前我还没有完美的实现方案,只能带有众多缺陷的去实现。如果我们只是想在关闭窗口前执行函数那就使用时间差区分即可。

相关推荐
moshuying15 分钟前
ESP32 墨水屏金价牌(上):从点亮到把图片推过去
前端
李剑一22 分钟前
别再抬杠,前端岗已经没了!无论前后端,我们最终都要成“全干”工程师
前端·面试
Highcharts.js23 分钟前
Highcharts 仪表盘与速度仪图表库介绍
前端·信息可视化·仪表板·highcharts·图表开发·图表库·仪表可视化
愚坤1 小时前
前端真有意思,JS还能独立做项目?
前端·javascript·github
SGAMERrain1 小时前
# Nuxt 4 + MediaPipe:如何在浏览器中实现本地 AI 人脸分析?
前端
github_is_geeksKai2 小时前
浏览器端文件处理的边界:PDF 面单、GPX 隐私与 EPUB 修复
前端
李纲明2 小时前
微信小程序 getSystemInfo 提示已废弃、屏幕高度算错胶囊还对不齐?getWindowInfo 和 getDeviceInfo 怎么接才稳
javascript·微信小程序·小程序·小程序开发·devdiy
deli0073 小时前
从一句反馈到一次升级:Mystudy 的自进化实践
前端
FungLeo3 小时前
成为全栈·Vue 管理后台篇·用 fetch 建一层可控的请求内核
前端·javascript·vue.js·http·fetch·formdata·接口封装
用户84298142418104 小时前
ByteJS,让重要的 JavaScript 以字节码运行。
javascript