分享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调用WebService的示例
Apr 07 Javascript
SOSO地图API使用(一)在地图上画圆实现思路与代码
Jan 15 Javascript
JS实现OCX控件的事件响应示例
Sep 17 Javascript
Jquery easyui 实现动态树
Nov 17 Javascript
jQuery中通过ajax调用webservice传递数组参数的问题实例详解
May 20 Javascript
Javascript将数字转化成为货币格式字符串
Jun 22 Javascript
vue.js学习笔记之绑定style样式和class列表
Oct 31 Javascript
通过bootstrap全面学习less
Nov 09 Javascript
jQuery 实现图片的依次加载图片功能
Jul 06 jQuery
js前端导出Excel的方法
Nov 01 Javascript
Vue2.x通用编辑组件的封装及应用详解
May 28 Javascript
Vue实现可移动水平时间轴
Jun 29 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 Ajax实现页面无刷新发表评论
2007/01/02 PHP
C/S和B/S两种架构区别与优缺点分析
2014/10/23 PHP
php die()与exit()的区别实例详解
2016/12/03 PHP
yii框架redis结合php实现秒杀效果(实例代码)
2017/10/26 PHP
PHP实现在对象之外访问其私有属性private及保护属性protected的方法
2017/11/20 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
php分享朋友圈的实现代码
2019/02/18 PHP
JavaScript面向对象(极简主义法minimalist approach)
2012/07/17 Javascript
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
js图片加载效果实例代码(延迟加载+瀑布流加载)
2017/05/12 Javascript
JS FormData上传文件的设置方法
2017/07/05 Javascript
bootstrap精简教程_动力节点Java学院整理
2017/07/14 Javascript
原生js实现仿window10系统日历效果的实例
2017/10/31 Javascript
Vue实现PopupWindow组件详解
2018/04/28 Javascript
react native 文字轮播的实现示例
2018/07/27 Javascript
js中Array对象的常用遍历方法详解
2019/01/17 Javascript
VUE注册全局组件和局部组件过程解析
2019/10/10 Javascript
ES5新增数组的实现方法
2020/05/12 Javascript
JS前端基于canvas给图片添加水印
2020/11/11 Javascript
布同 Python中文问题解决方法(总结了多位前人经验,初学者必看)
2011/03/13 Python
Python创建日历实例
2014/08/21 Python
Python字符串格式化输出方法分析
2016/04/13 Python
Python递归函数 二分查找算法实现解析
2019/08/12 Python
将labelme格式数据转化为标准的coco数据集格式方式
2020/02/17 Python
如何在python中处理配置文件代码实例
2020/09/27 Python
Python importlib模块重载使用方法详解
2020/10/13 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
标签和贴纸印刷:Lightning Labels
2018/03/22 全球购物
拉斯维加斯城市观光通行证:Las Vegas Pass
2019/05/21 全球购物
护士岗位职责
2014/02/16 职场文书
市级青年文明号申报材料
2014/05/26 职场文书
新闻编辑求职信
2014/07/13 职场文书
市级绿色学校申报材料
2014/08/25 职场文书
合作协议书模板2014
2014/09/26 职场文书
基于Python编写简易版的天天跑酷游戏的示例代码
2022/03/23 Python
victoriaMetrics库布隆过滤器初始化及使用详解
2022/04/05 Golang