分享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 相关文章推荐
JavaScript基本编码模式小结
May 23 Javascript
Javascript实现滚动图片新闻的实例代码
Nov 27 Javascript
jquery批量设置属性readonly和disabled的方法
Jan 24 Javascript
JavaScript获取当前网页标题(title)的方法
Apr 03 Javascript
在JavaScript中操作数组之map()方法的使用
Jun 09 Javascript
使用RequireJS优化JavaScript引用代码的方法
Jul 01 Javascript
javascript拖拽应用实例
Mar 25 Javascript
返回函数的JavaScript函数
Jun 14 Javascript
获取jqGrid中选择的行的数据
Nov 30 Javascript
利用jQuery.Validate异步验证用户名是否存在(推荐)
Dec 09 Javascript
微信小程序request请求后台接口php的实例详解
Sep 20 Javascript
k8s node节点重新加入master集群的实现
Feb 22 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
转生史莱姆:萌王第一次撸串开心到飞起,哥布塔撸串却神似界王神
2018/11/30 日漫
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
2014/05/12 PHP
php生成二维码时出现中文乱码的解决方法
2014/12/18 PHP
php微信支付之APP支付方法
2015/03/04 PHP
php返回相对时间(如:20分钟前,3天前)的方法
2015/04/14 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
详谈symfony window下的安装 安装时候出现的问题以及解决方法
2017/09/28 PHP
JavaScript 组件之旅(四):测试 JavaScript 组件
2009/10/28 Javascript
JavaScript省市联动实现代码
2014/02/15 Javascript
JavaScript中的值类型详细介绍
2014/12/29 Javascript
详解Bootstrap创建表单的三种格式(一)
2016/01/04 Javascript
浅谈javascript中的call、apply、bind
2016/03/06 Javascript
总结在前端排序中遇到的问题
2016/07/19 Javascript
js实现延迟加载的几种方法
2017/04/24 Javascript
详解tween.js的使用教程
2017/09/14 Javascript
Vue+Express实现登录注销功能的实例代码
2019/05/05 Javascript
Layer.js实现表格溢出内容省略号显示,悬停显示全部的方法
2019/09/16 Javascript
NodeJS http模块用法示例【创建web服务器/客户端】
2019/11/05 NodeJs
JS检测浏览器开发者工具是否打开的方法详解
2020/10/02 Javascript
[01:58]2018DOTA2亚洲邀请赛趣味视频——交流
2018/04/03 DOTA
python转换摩斯密码示例
2014/02/16 Python
python轻松实现代码编码格式转换
2015/03/26 Python
python 全文检索引擎详解
2017/04/25 Python
Python实现的自定义多线程多进程类示例
2018/03/23 Python
浅谈Python大神都是这样处理XML文件的
2019/05/31 Python
pyenv与virtualenv安装实现python多版本多项目管理
2019/08/17 Python
python shapely.geometry.polygon任意两个四边形的IOU计算实例
2020/04/12 Python
Python使用Numpy模块读取文件并绘制图片
2020/05/13 Python
html5自带表单验证体验优化及提示气泡修改功能
2017/09/12 HTML / CSS
彪马美国官网:PUMA美国
2017/03/09 全球购物
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
六一亲子活动总结
2014/07/01 职场文书
乡镇消防安全责任书
2014/07/23 职场文书
以权谋私检举信范文
2015/03/02 职场文书
会计入职心得体会
2016/01/22 职场文书
简单介绍Python的第三方库yaml
2021/06/18 Python