分享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中this的作用域
Aug 12 Javascript
jquery checkbox 勾选的bug问题解决方案与分析
Nov 13 Javascript
js+html5实现canvas绘制镂空字体文本的方法
Jun 05 Javascript
AngularJS基础 ng-click 指令示例代码
Aug 01 Javascript
javascript实现获取图片大小及图片等比缩放的方法
Nov 24 Javascript
用jquery的attr方法实现图片切换效果
Feb 05 Javascript
Bootstrap学习笔记 轮播(Carousel)插件
Mar 21 Javascript
Vue原理剖析 实现双向绑定MVVM
May 03 Javascript
Vue2.0子同级组件之间数据交互方法
Feb 28 Javascript
vue数据初始化initState的实例详解
Apr 11 Javascript
vue中使用带隐藏文本信息的图片、图片水印的方法
Apr 24 Javascript
详解如何修改 node_modules 里的文件
May 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
配置Nginx+PHP的正确思路与过程
2016/05/10 PHP
php检查函数必传参数是否存在的实例详解
2017/08/28 PHP
php取出数组单个值的方法
2018/03/12 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
我见过最全的个人js加解密功能页面
2007/12/12 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 简史
2015/01/09 Javascript
jquery比较简洁的软键盘特效实现方法
2015/03/19 Javascript
纯css下拉菜单 无需js
2016/08/15 Javascript
用NodeJS实现批量查询地理位置的经纬度接口
2016/08/16 NodeJs
AngularJS实现在ng-Options加上index的解决方法
2016/11/03 Javascript
AngularJS 使用ng-repeat报错 [ngRepeat:dupes]
2017/01/19 Javascript
jQuery使用eraser.js插件实现擦除、刮刮卡效果的方法【附eraser.js下载】
2017/04/28 jQuery
JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)
2017/05/17 Javascript
React + webpack 环境配置的方法步骤
2017/09/07 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
vue项目初始化到登录login页面的示例
2019/10/31 Javascript
Vue2.X和Vue3.0数据响应原理变化的区别
2019/11/07 Javascript
js页面加载后执行的几种方式小结
2020/01/30 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
Python对文件操作知识汇总
2016/05/15 Python
python中requests小技巧
2017/05/10 Python
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
python中int与str互转方法
2018/07/02 Python
python 将json数据提取转化为txt的方法
2018/10/26 Python
Python 新建文件夹与复制文件夹内所有内容的方法
2018/10/27 Python
python3.6利用pyinstall打包py为exe的操作实例
2018/10/31 Python
python字符串,元组,列表,字典互转代码实例详解
2020/02/14 Python
python 将视频 通过视频帧转换成时间实例
2020/04/23 Python
css3翻牌翻数字的示例代码
2020/02/07 HTML / CSS
视光学专业毕业生推荐信
2013/10/28 职场文书
党的群众路线教育实践活动对照检查材料思想汇报
2014/09/19 职场文书
2016年党员读书月活动总结
2016/04/06 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
CSS的class与id常用的命名规则
2021/05/18 HTML / CSS
Navicat连接MySQL错误描述分析
2021/06/02 MySQL
Python数据结构之队列详解
2022/03/21 Python