分享JavaScript获取网页关闭与取消关闭的事件


Posted in Javascript onDecember 13, 2013

在做Web开发时,我们经常用到页面关闭事件onbeforeunload,可以给用户一个选择放弃关闭的机会,就比如这个博客编辑器。如果用户选择了离开,那么onunload事件自然会触发;但若用户选择了取消,又该如何检测呢?

我们假定一个页面离开取消事件,叫做onunloadcancel。显然,这个事件应触发在用户按下对话框的取消按钮之后。但关闭提示对话框的触发流程并不是那么简单。我们先来回顾下这个过程:

window.onbeforeunload = function()
{
    return "真的离开?";
}

当用户准备离开页面(比如按下关闭按钮,或者刷新页面等等),onbeforeunload事件触发。我们的脚本无法在这个事件里决定是否阻止页面的关闭,唯一能做到的只有返回一个字符串,这个字符串仅作为说明文字出现在关闭选择对话框里,用户可以选择关闭,或者不关闭。但究竟选择哪个,我们无从得知。

然而仔细分析下这个问题,其实不然。 如果用户真选择了关闭页面,那么之后所有的运行代码都byebye了;而继续留在页面的话,就当什么都没发生过,除了onbeforeunload事件。所以,我们在onbeforeunload事件里做点小花招,在此注册个几毫秒之后启动的定时器,如果页面真关闭了,那么这个定时器当然是作废了;那么页面还在,几毫秒的延时对于这个本来就是异步的界面交互事件也没有什么误差。

<script language="JavaScript">
window.onbeforeunload = function()
{
    setTimeout(onunloadcancel, 10);
    return "真的离开?";
}
window.onunloadcancel = function()
{
    alert("取消离开");
}
</script>

我们使用setTimeout,延时10ms执行onunloadcancel。如果页面真关闭了,定时器当然都销毁;反之继续。但在测试中,发现FireFox有个两个BUG:

有时按下关闭按钮,也会执行onunloadcancel,并且有个对话框一闪而过。如果换成while(1);浏览器会一直卡死,这说明onunloadcancel确实是执行了,只是销毁了界面,但并没有暂停脚本的运行。
如果是通过刷新页面的方式离开,仅执行一次onbeforeunload,但点击X按钮关闭页面,会执行两次onbeforeunload。因此我们还需在完善下,以便兼容FF。

<script language="JavaScript">
var _t;
window.onbeforeunload = function()
{
    setTimeout(function(){_t = setTimeout(onunloadcancel, 0)}, 0);
    return "真的离开?";
}
window.onunloadcancel = function()
{
    clearTimeout(_t);
    alert("取消离开");
}
</script>

这里使用了一种我也说不出原因的办法,应该算是hack,解决了FF下的bug。
Javascript 相关文章推荐
Firefox中autocomplete=&quot;off&quot; 设置不起作用Bug的解决方法
Mar 25 Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
Sep 14 Javascript
javascript常用代码段搜集
Dec 04 Javascript
jQuery.each使用详解
Jul 07 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
Aug 19 Javascript
vue实现登陆登出的实现示例
Sep 15 Javascript
基于jQuery.i18n实现web前端的国际化
May 04 jQuery
微信小程序实现tab左右切换效果
Nov 15 Javascript
js变量值传到php过程详解 将php解析成数据
Jun 26 Javascript
Vue搭建后台系统需要注意的问题
Nov 08 Javascript
Vue移动端实现图片上传及超过1M压缩上传
Dec 23 Javascript
一文了解JavaScript用Element Traversal新属性遍历子元素
Nov 27 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
Dec 13 #Javascript
浅析XMLHttpRequest的缓存问题
Dec 13 #Javascript
xmlhttp缓存清除的2种解决方法
Dec 13 #Javascript
js获取url参数代码实例分享(JS操作URL)
Dec 13 #Javascript
js获取html页面节点方法(递归方式)
Dec 13 #Javascript
jquery 合并内容相同的单元格(示例代码)
Dec 13 #Javascript
javascript读取xml实现javascript分页
Dec 13 #Javascript
You might like
PHP编码转换
2012/11/05 PHP
PHP递归调用的小技巧讲解
2013/02/19 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
2013/08/10 PHP
Win10 下安装配置IIS + MySQL + nginx + php7.1.7
2017/08/04 PHP
php+ajax实现仿百度查询下拉内容功能示例
2017/10/20 PHP
在 Laravel 中动态隐藏 API 字段的方法
2019/10/25 PHP
PHP设计模式之 策略模式Strategy详解【对象行为型】
2020/05/01 PHP
超级退弹代码
2008/07/07 Javascript
js获取当前页面路径示例讲解
2014/01/08 Javascript
JavaScript编程中window的location与history对象详解
2015/10/26 Javascript
Javascript typeof与instanceof的区别
2016/10/18 Javascript
从零开始学习Node.js系列教程之设置HTTP头的方法示例
2017/04/13 Javascript
Vue组件选项props实例详解
2017/08/18 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
微信小程序实现全局搜索代码高亮的示例
2018/03/30 Javascript
webpack4 处理CSS的方法示例
2018/09/03 Javascript
webpack配置proxyTable时pathRewrite无效的解决方法
2018/12/13 Javascript
为什么Vue3.0使用Proxy实现数据监听(defineProperty表示不背这个锅)
2019/10/14 Javascript
pycharm 使用心得(六)进行简单的数据库管理
2014/06/06 Python
Python中优化NumPy包使用性能的教程
2015/04/23 Python
python文件名和文件路径操作实例
2017/09/29 Python
python解决字符串倒序输出的问题
2018/06/25 Python
Python和Go语言的区别总结
2019/02/20 Python
使用PyOpenGL绘制三维坐标系实例
2019/12/24 Python
python实现俄罗斯方块游戏(改进版)
2020/03/13 Python
Python闭包及装饰器运行原理解析
2020/06/17 Python
Python绘图之二维图与三维图详解
2020/08/04 Python
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
美国卡车、吉普车和SUV零件网站:4 Wheel Parts
2016/11/24 全球购物
写好自荐信的技巧
2013/11/08 职场文书
公司感恩节活动策划书
2014/10/11 职场文书
2015羊年春节慰问信
2015/02/14 职场文书
人生遥控器观后感
2015/06/11 职场文书
MySQL大小写敏感的注意事项
2021/05/24 MySQL
Maven学习----Maven安装与环境变量配置教程
2021/06/29 Java/Android