分享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闭包(Closure)详解
May 05 Javascript
jQuery图片旋转插件jQueryRotate.js用法实例(附demo下载)
Jan 21 Javascript
新入门node.js必须要知道的概念(必看篇)
Aug 10 Javascript
jQuery动态修改字体大小的方法【测试可用】
Sep 09 Javascript
Angularjs 与 bower安装和使用详解
May 11 Javascript
Kotlin学习第一步 kotlin语法特性
May 25 Javascript
js登录滑动验证的实现(不滑动无法登陆)
Jan 03 Javascript
详解Vue 多级组件透传新方法provide/inject
May 09 Javascript
详解使用vue-admin-template的优化历程
May 20 Javascript
jQuery实现参数自定义的文字跑马灯效果
Aug 15 jQuery
详解在vue-test-utils中mock全局对象
Nov 07 Javascript
VUE 动态组件的应用案例分析
Dec 02 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功能多于Memcache
2011/06/14 PHP
详解php的魔术方法__get()和__set()使用介绍
2012/09/19 PHP
php语言流程控制中的主动与被动
2012/11/05 PHP
浅析PHP中call user func()函数及如何使用call user func调用自定义函数
2015/11/05 PHP
php实现数组纵向转横向并过滤重复值的方法分析
2017/05/29 PHP
PHP微信开发之微信录音临时转永久存储
2018/01/26 PHP
PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
2019/12/04 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
使用jQuery fancybox插件打造一个实用的数据传输模态弹出窗体
2013/01/15 Javascript
JavaScript中的闭包(Closure)详细介绍
2014/12/30 Javascript
jQuery实现仿路边灯箱广告图片轮播效果
2015/04/15 Javascript
学习JavaScript正则表达式
2015/11/13 Javascript
JavaScript原生对象常用方法总结(推荐)
2016/05/13 Javascript
JavaScript 中有关数组对象的方法(详解)
2016/08/15 Javascript
新闻上下滚动jquery 超简洁(必看篇)
2017/01/21 Javascript
jQuery Pagination分页插件使用方法详解
2017/02/28 Javascript
JavaScript实现元素滚动条到达一定位置循环追加内容
2017/12/28 Javascript
详解在create-react-app使用less与antd按需加载
2018/12/06 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
如何实现双向绑定mvvm的原理实现
2019/05/28 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
js实现简单点赞操作
2020/03/17 Javascript
python删除指定类型(或非指定)的文件实例详解
2015/07/06 Python
合并百度影音的离线数据( with python 2.3)
2015/08/04 Python
Python 字符串换行的多种方式
2018/09/06 Python
Python 实现域名解析为ip的方法
2019/02/14 Python
PyQt5+python3+pycharm开发环境配置教程
2020/03/24 Python
Python使用matplotlib绘制圆形代码实例
2020/05/27 Python
Python实现GIF图倒放
2020/07/16 Python
pytorch学习教程之自定义数据集
2020/11/10 Python
python利用后缀表达式实现计算器功能
2021/02/22 Python
Speedo速比涛中国官方网站:全球领先泳装运动品牌
2018/04/24 全球购物
Joules官网:女士、男士和儿童服装和鞋类
2018/10/23 全球购物
学校世界艾滋病日宣传活动总结
2015/05/05 职场文书
从严治党主题教育活动总结
2015/05/07 职场文书
大学生,三分钟即兴演讲稿
2019/07/22 职场文书