分享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 相关文章推荐
JS实现遮罩层效果的简单实例
Nov 12 Javascript
js判断某个方法是否存在实例代码
Jan 10 Javascript
浅析JavaScript作用域链、执行上下文与闭包
Feb 01 Javascript
jQuery树形插件jquery.simpleTree.js用法分析
Sep 05 Javascript
js 性能优化之快速响应的用户界面
Feb 15 Javascript
使用vue.js编写蓝色拼图小游戏
Mar 17 Javascript
详谈js对url进行编码和解码(三种方式的区别)
Aug 16 Javascript
vue实现自定义多选与单选的答题功能
Jul 05 Javascript
微信小程序多音频播放进度条问题
Aug 28 Javascript
使用JavaScript解析URL的方法示例
Mar 01 Javascript
JS实现的冒泡排序,快速排序,插入排序算法示例
Mar 02 Javascript
Vue+Koa2+mongoose写一个像素绘板的实现方法
Sep 10 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
PHP4中实现动态代理
2006/10/09 PHP
PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
2012/06/07 PHP
深入分析php中接口与抽象类的区别
2013/06/08 PHP
注意:php5.4删除了session_unregister函数
2013/08/05 PHP
destoon数据库表说明汇总
2014/07/15 PHP
php判断访问IP的方法
2015/06/19 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
防止xss和sql注入:JS特殊字符过滤正则
2013/04/18 Javascript
Node.js的特点和应用场景介绍
2014/11/04 Javascript
详解javascript new的运行机制
2016/01/26 Javascript
Node.js文件操作方法汇总
2016/03/22 Javascript
浅谈json取值(对象和数组)
2016/06/24 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
原生javascript移动端滑动banner效果
2017/03/10 Javascript
js 判断一个数字是不是2的n次方幂的实例
2017/11/26 Javascript
js replace替换字符串同时替换多个方法
2018/11/27 Javascript
在vue项目中优雅的使用SVG的方法实例详解
2018/12/03 Javascript
JavaScript创建对象的四种常用模式实例分析
2019/01/11 Javascript
详解webpack4.x之搭建前端开发环境
2019/03/28 Javascript
[50:27]Secret vs VG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python类的多重继承问题深入分析
2014/11/09 Python
在Python中操作列表之List.append()方法的使用
2015/05/20 Python
python pands实现execl转csv 并修改csv指定列的方法
2018/12/12 Python
Python 经典算法100及解析(小结)
2019/09/13 Python
python3.8 微信发送服务器监控报警消息代码实现
2019/11/05 Python
Python实现代码块儿折叠
2020/04/15 Python
Selenium 配置启动项参数的方法
2020/12/04 Python
CSS3 创建网页动画实现弹跳球动效果
2018/10/30 HTML / CSS
h5移动端调用支付宝、微信支付的实现
2020/06/08 HTML / CSS
Bally巴利英国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/05/07 全球购物
工程项目建议书范文
2014/03/12 职场文书
军训拉歌口号
2014/06/13 职场文书
2015教师见习期工作总结
2014/12/12 职场文书
90行Python代码开发个人云盘应用
2021/04/20 Python
悬疑名作《朋友游戏》动画无字ED宣传片 新角色公开
2022/04/13 日漫