分享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 相关文章推荐
Extjs 几个方法的讨论
Jan 28 Javascript
基于JQuery的asp.net树实现代码
Nov 30 Javascript
深入理解JavaScript系列(4) 立即调用的函数表达式
Jan 15 Javascript
让人印象深刻的10个jQuery手风琴效果应用
May 08 Javascript
简洁实用的BootStrap jQuery手风琴插件
Aug 31 Javascript
jquery.uploadView 实现图片预览上传功能
Aug 10 jQuery
用JS实现根据当前时间随机生成流水号或者订单号
May 31 Javascript
vue安装和使用scss及sass与scss的区别详解
Oct 15 Javascript
原生JS实现动态添加新元素、删除元素方法
May 05 Javascript
JS图片懒加载的优点及实现原理
Jan 10 Javascript
js实现圆形显示鼠标单击位置
Feb 11 Javascript
js+canvas实现刮刮奖功能
Sep 13 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 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
DEDE采集大师官方留后门的删除办法
2011/01/08 PHP
使用PHP会话(Session)实现用户登陆功能
2013/06/29 PHP
php遍历目录与文件夹的多种方法详解
2013/11/14 PHP
基于JQUERY的两个ListBox子项互相调整的实现代码
2011/05/07 Javascript
等待指定时间后自动跳转或关闭当前页面的js代码
2013/07/09 Javascript
纯文字版返回顶端的js代码
2013/08/01 Javascript
DOM基础教程之事件类型
2015/01/20 Javascript
理解Javascript的动态语言特性
2015/06/17 Javascript
javascript 闭包详解
2015/07/02 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
js 定位到某个锚点的方法
2016/11/19 Javascript
js实现年月日表单三级联动
2020/04/17 Javascript
JavaScript如何获取一个元素的样式信息
2019/07/29 Javascript
JS数据类型(基本数据类型、引用数据类型)及堆和栈的区别分析
2020/03/04 Javascript
vue el-tree 默认展开第一个节点的实现代码
2020/05/15 Javascript
python 根据正则表达式提取指定的内容实例详解
2016/12/04 Python
Django实现自定义404,500页面教程
2017/03/26 Python
Python构建XML树结构的方法示例
2017/06/30 Python
在Django中输出matplotlib生成的图片方法
2018/05/24 Python
浅析python3中的os.path.dirname(__file__)的使用
2018/08/30 Python
python使用循环打印所有三位数水仙花数的实例
2018/11/13 Python
如何使用Python 打印各种三角形
2019/06/28 Python
django项目简单调取百度翻译接口的方法
2019/08/06 Python
在Python中字符串、列表、元组、字典之间的相互转换
2019/11/15 Python
Tensorflow 使用pb文件保存(恢复)模型计算图和参数实例详解
2020/02/11 Python
python plt可视化——打印特殊符号和制作图例代码
2020/04/17 Python
python判断是空的实例分享
2020/07/06 Python
html5教程制作简单画板代码分享
2013/12/04 HTML / CSS
阿迪达斯印度官方商城:adidas India
2017/03/26 全球购物
技术副厂长岗位职责
2013/12/26 职场文书
银行职业规划书范文
2013/12/28 职场文书
中学生学雷锋活动心得体会
2014/03/10 职场文书
学习十八大的心得体会
2014/09/12 职场文书
2014年扶贫帮困工作总结
2014/12/09 职场文书
2015年工商所工作总结
2015/05/21 职场文书