分享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 相关文章推荐
Array对象方法参考
Oct 03 Javascript
用JavaScript实现单继承和多继承的简单方法
Mar 29 Javascript
event对象的方法 兼容多浏览器
Jun 27 Javascript
jQuery AnythingSlider滑动效果插件
Feb 07 Javascript
js报错 Object doesn't support this property or method的原因分析
Mar 31 Javascript
js解决select下拉选不中问题
Oct 14 Javascript
JS中完美兼容各大浏览器的scrolltop方法
Apr 17 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
JS实现的表头列头固定页面功能示例
Jan 10 Javascript
JS实现加载时锁定HTML页面元素的方法
Jun 24 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
Oct 04 Javascript
nuxt引入组件和公共样式的操作
Nov 05 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.ini 中文版
2006/10/28 PHP
php中截取字符串支持utf-8
2007/01/18 PHP
PHP实现的简单mock json脚本分享
2015/02/10 PHP
PHP中Cookie的使用详解(简单易懂)
2017/04/28 PHP
给网站上的广告“加速”显示的方法
2007/04/08 Javascript
javascript数字格式化通用类 accounting.js使用
2012/08/24 Javascript
只需一行代码,轻松实现一个在线编辑器
2013/11/12 Javascript
JQuery与JS里submit()的区别示例介绍
2014/02/17 Javascript
拥有一个属于自己的javascript表单验证插件
2016/03/24 Javascript
深入解析桶排序算法及Node.js上JavaScript的代码实现
2016/07/06 Javascript
微信小程序tabBar用法实例详解
2017/12/04 Javascript
JS实现TITLE悬停长久显示效果完整示例
2020/02/11 Javascript
Vue 实现可视化拖拽页面编辑器
2021/02/01 Vue.js
WebStorm无法正确识别Vue3组合式API的解决方案
2021/02/18 Vue.js
[02:37]2018DOTA2亚洲邀请赛赛前采访-EG篇
2018/04/03 DOTA
Python使用django获取用户IP地址的方法
2015/05/11 Python
python 递归深度优先搜索与广度优先搜索算法模拟实现
2018/10/22 Python
解决python xlrd无法读取excel文件的问题
2018/12/25 Python
Python单元测试模块doctest的具体使用
2020/02/10 Python
Tensorflow中的dropout的使用方法
2020/03/13 Python
Python调用shell命令常用方法(4种)
2020/05/11 Python
Python xlrd模块导入过程及常用操作
2020/06/10 Python
Python趣味入门教程之循环语句while
2020/08/26 Python
Python求区间正整数内所有素数之和的方法实例
2020/10/13 Python
python 使用cycle构造无限循环迭代器
2020/12/02 Python
python对输出的奇数偶数排序实例代码
2020/12/04 Python
如何用Python进行时间序列分解和预测
2021/03/01 Python
德国最大的设计师鞋网上商店:Budapester
2017/12/07 全球购物
ALDI奥乐齐官方海外旗舰店:德国百年超市
2017/12/27 全球购物
意大利制造的男鞋和女鞋:SCAROSSO
2018/03/07 全球购物
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
经济管理专业毕业生自荐信范文
2014/01/02 职场文书
应届大学生求职信
2014/07/20 职场文书
我的未来不是梦演讲稿
2014/09/02 职场文书
你离财务总监还有多远?速览CFO的岗位职责
2019/11/18 职场文书
拒绝盗图!教你怎么用python给图片加水印
2021/06/04 Python