分享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 学习笔记 Black.Caffeine 09.11.28
Nov 30 Javascript
js jquery数组介绍
Jul 15 Javascript
浅谈关于JavaScript的语言特性分析
Apr 11 Javascript
JavaScript中输出标签的方法
Aug 27 Javascript
浅谈javascript中基本包装类型
Jun 03 Javascript
基于JavaScript实现添加到购物车效果附源码下载
Aug 22 Javascript
Vue.js表单控件实践
Oct 27 Javascript
快速解决处理后台返回json数据格式的问题
Aug 07 Javascript
小程序实现列表多个批量倒计时
Jan 29 Javascript
JS事件绑定的常用方式实例总结
Mar 02 Javascript
JavaScript使用prototype属性实现继承操作示例
May 22 Javascript
Nuxt的路由动画效果案例
Nov 06 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 Memcached应用实现代码
2010/02/08 PHP
php 数组的一个悲剧?
2011/05/11 PHP
php实现微信发红包功能
2018/07/13 PHP
php7下的filesize函数
2019/09/30 PHP
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
PHP 出现 http500 错误的解决方法
2021/03/09 PHP
JavaScript监测ActiveX控件是否已经安装过的代码
2008/09/02 Javascript
JQuery调webservice实现邮箱验证(检测是否可用)
2013/05/21 Javascript
简单方法判断JavaScript对象为null或者属性为空
2014/09/26 Javascript
jQuery中extend函数的实现原理详解
2015/02/03 Javascript
浅谈javascript中基本包装类型
2015/06/03 Javascript
在React框架中实现一些AngularJS中ng指令的例子
2016/03/06 Javascript
jqGrid 学习笔记整理——进阶篇(一 )
2016/04/17 Javascript
bootstrap中添加额外的图标实例代码
2017/02/15 Javascript
微信小程序中post方法与get方法的封装
2017/09/26 Javascript
VUE2.0中Jsonp的使用方法
2018/05/22 Javascript
vuejs数据超出单行显示更多,点击展开剩余数据实例
2019/05/05 Javascript
详解Vue、element-ui、axios实现省市区三级联动
2019/05/07 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
webpack3.0升级4.0的方法步骤
2020/04/02 Javascript
JS实现密码框效果
2020/09/10 Javascript
[00:53]2015国际邀请赛 中国区预选赛一触即发
2015/05/14 DOTA
[00:12]2018DOTA2亚洲邀请赛 Sccc亮相SOLO赛,今年他又会有什么样的战绩?
2018/04/06 DOTA
python 爬虫一键爬取 淘宝天猫宝贝页面主图颜色图和详情图的教程
2018/05/22 Python
Python将多个list合并为1个list的方法
2018/06/27 Python
Python中对数组集进行按行打乱shuffle的方法
2018/11/08 Python
Python OS模块实例详解
2019/04/15 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
python 命令行传入参数实现解析
2019/08/30 Python
Python+Opencv身份证号码区域提取及识别实现
2020/08/25 Python
python字典按照value排序方法
2020/12/28 Python
施华洛世奇澳大利亚官网:SWAROVSKI澳大利亚
2017/01/06 全球购物
师范应届生语文教师求职信
2013/10/29 职场文书
2019交通安全宣传标语集锦!
2019/06/28 职场文书
Java并发编程之原子性-Atomic的使用
2022/03/16 Java/Android
Python实现双向链表基本操作
2022/05/25 Python