转载:http://www.w3help.org/zh-cn/causes/BX2047

标准参考

无。

问题描述

一般情况下,onbeforeunload 事件处理函数内会写入一些提示性语句,当用户的浏览器跳转到其他页面时,用来提醒用户当前页面将要跳转,请用户决定是否观看新页面。
或者在 onbeforeunload 事件内处理一些业务逻辑,在浏览器跳转到新页面之前 ,执行一些业务逻辑,如保存用户浏览信息等。

简单的说这个事件应仅在页面 URL 发生变化时触发,但是在 IE 中 使用 JavaScript 伪协议执行脚本程序时,也会触发 onbeforeunload 事件。

造成的影响

此问题不会造成大问题,但会导致不友好的提示出现,稍微影响用户操作体验。

受影响的浏览器

所有浏览器  

问题分析

onbeforeunload 事件是非 W3C DOM-Event 标准事件,它属于 BOM (Browser Object Model) 范畴。到现在为止 BOM 还没有被标准化,它由各个浏览器厂商制定,因此会有实现差异。

时至今日,HTML5 规范草案中已经开始标准化 BOM,遗憾的是 onbeforeunload 事件的触发条件还没有在草案中作出详细说明。

更多内容可参考:6.1.6.2 Event handlers on elements, Document objects, and Window objects

最初的 onbeforeunload 事件支持是由 IE4.0 版本提供,存在于 BODY、FRAMESET 的 DOM 对象及 window 对象之中,随后被其他浏览器复制,但具体事件触发方式并没有统一。

根据 MSDN 中描述,IE 的 onbeforeunload 事件可由以下这些条件触发:

  • 关闭当前浏览器窗口。
  • 导航到另一个进入一个新的地址或选择一个喜欢的位置。
  • 单击后退,前进,刷新,或主页按钮。
  • 点击一个链接到新页面。
  • 调用 超链接的 click 方法。
  • 调用 document.write 方法。
  • 调用 document.open 方法。
  • 调用 document.close 方法。
  • 调用 window.close 方法。
  • 调用 window.open 方法,窗口名称设置值为 _self。
  • 调用 window.navigate 或 NavigateAndFind 方法。
  • 调用 location.replace 方法。
  • 调用 location.reload 方法。
  • 指定一个 location.href 属性的新值。
  • 使用 submit 按键提交表单,或调用 form.submit 方法。

更详细的说明可以查考 MSDN 原文:onbeforeunload Event

在这些触发条件中绝大多数都使页面产生了跳转,但还缺少一些常见情况说明,即页面 URL 可能发生了变化但没有产生跳转。比如 "javascipt:" "mailto:" 等常见的浏览器内置伪协议,以及由第三方或用户自定义的为协议时,页面并不跳转,而是根据伪协议执行指定的行为。这个情况应加入到触发条件中。

根据以上所有这些触发条件,我们构建如下代码来检测各浏览器对 onbeforeunload 事件的支持程度与触发条件:

<script>
window.onbeforeunload=function(){
  return "请点击取消留在此页";
}
</script>
请手工关闭当前浏览器窗口。<br/>
请手工单击后退,前进,刷新,或主页按钮。<br/>
请手工在地址栏输入其他页面地址或从收藏夹、历史记录中将页面导航其他站点。<br/>
<a href="http://www.google.com" id="A">点击一个链接到新页面</a><br />
<button onclick="document.getElementById('A').click()">调用 anchor.click 方法</button><br />
<button onclick="document.write('A')">调用 document.write 方法</button><br />
<button onclick="document.open()">调用 document.open 方法</button><br />
<button onclick="document.close()">调用 document.close 方法。</button><br />
<button onclick="window.open('http://www.google.com','_self')">调用 window.open方法,窗口名称设置值为 _self。</button><br />
<button onclick="try{window.navigate('http://www.google.com')}catch(e){alert('不支持此方法')}">调用 window.navigate 方法</button><br />
<button onclick="try{window.external.NavigateAndFind('http://www.google.com','','')}catch(e){alert('不支持此方法')}">调用 NavigateAndFind 方法</button><br />
<button onclick="location.replace('http://www.google.com')">调用 location.replace 方法</button><br />
<button onclick="location.reload()">调用 location.reload 方法</button><br />
<button onclick="location.href='http://www.google.com'">指定一个 location.href 属性的新值</button><br />
<form action="http://www.google.com" id="B">
<input type="submit" value="提交具有action属性的一个表单">
</form>
<button onclick="document.getElementById('B').submit()">调用 form.submit 方法</button>
<a href="javascript:">调用 javascipt: 伪协议</a><br />
<a href="mailto:"&gt;调用&nbsp;mailto:&nbsp;伪协议&lt;/a&gt;&lt;br&nbsp;/&gt;<br />&lt;a&nbsp;href="custom:">调用自定义伪协议</a>

执行结果汇总入表:

  IE Firefox Chrome Safari Opera
关闭当前浏览器窗口 事件被触发 事件被触发 事件被触发 不支持该事件
导航到另一个进入一个新的地址或选择一个喜欢的位置 事件被触发 事件被触发 事件被触发 不支持该事件
单击后退,前进,刷新,或主页按钮 事件被触发 事件被触发 事件被触发 不支持该事件
点击一个链接到新页面 事件被触发 事件被触发 事件被触发 不支持该事件
调用 anchor.click方法 事件被触发 不支持此方法1 不支持此方法1 不支持该事件
调用 document.write方法 事件被触发 事件被触发 事件未触发 不支持该事件
调用 document.open方法 事件被触发 事件被触发 事件未触发 不支持该事件
调用 document.close方法 事件未触发 事件未触发 事件未触发 不支持该事件
调用 window.open方法,窗口名称设置值为 _self 事件被触发 事件被触发 事件被触发 不支持该事件
调用 window.navigate 事件被触发 不支持此方法2 不支持此方法2 不支持该事件
调用 NavigateAndFind方法 事件被触发 不支持此方法3 不支持此方法3 不支持此方法3
调用 location.replace 方法 事件被触发 事件被触发 事件被触发 不支持该事件
调用 location.reload 方法 事件被触发 事件被触发 事件被触发 不支持该事件
指定一个 location.href 属性的新值 事件被触发 事件被触发 事件被触发 不支持该事件
使用 submit 按键提交表单 事件被触发 事件被触发 事件被触发 不支持该事件
调用 form.submit 方法 事件被触发 事件被触发 事件被触发 不支持该事件
调用 javascipt: 伪协议 事件被触发 事件未触发 事件未触发 不支持该事件
调用 mailto: 伪协议 事件未触发 事件未触发 事件被触发 不支持该事件
调用自定义伪协议 事件被触发 事件被触发 事件被触发 不支持该事件

注 1: 直接调用链接元素的 click 方法模拟鼠标点击事件,只有 IE 和 Opera 支持,BX9052: IE Opera 支持使用 window.navigate 方法控制页面跳转 和 SD9025: IE6 IE7 IE8 Opera 支持除 INPUT 和 BUTTON 元素以外的其他元素的 'click' 方法。 
注 2: 使用 window.navigate 方法导航网页仅被 IE Opera 支持,可参考 MSDN 原文:navigate Method。 
注 3: NavigateAndFind 方法处于 window.external 对象中,external 对象也仅 IE 支持,可参考 MSDN 原文:NavigateAndFind Method 和本站文章 BT9012: IE 的 external 对象提供的方法是 IE 特有的

结合汇总表可以看出:

  • Opera 并不支持 onbeforeunload 事件。
  • Chrome Safari 在调用 document.write、document.open、document.close 方法以及 "javascipt:" 伪协议时,不会触发 onbeforeunload 事件。
  • Firefox 在调用 document.close 方法和 "javascipt:"、"mailto:" 伪协议时,不会触发 onbeforeunload 事件。
  • IE 浏览器在调用 document.close 方法和 "mailto:" 伪协议时,不会触发 onbeforeunload 事件。

解决方案

onbeforeunload 事件还未标准化,各浏览器的支持以及事件触发条件差异较多,需谨慎使用。

如必须在非 Opera 浏览器内使用该事件,应尽量避免在页面中调用常见的 "javascrpt:" 以及其他伪协议,以此回避不同浏览器中 onbeforeunload 事件被频繁触发。

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.10
Chrome 7.0.544.0 dev
Safari 5.0.2
Opera 10.62
测试页面: onbeforeunload_event_differences.html
本文更新时间: 2010-10-13

关键字

javascipt URL Protocol onbeforeunload

各浏览器对 onbeforeunload 事件的支持与触发条件实现有差异的更多相关文章

  1. 10、网页制作Dreamweaver(扩展:各浏览器对 onunload 事件的支持与触发条件实现有差异)

    标准参考 在 HTML 4.01 规范中关于 onunload 事件的描述是:当 document 从 window 中移除时,触发 onunload 事件. 关于 HTML 4.01 规范中 onu ...

  2. 关于windows phone 8.1系统手机对html5触摸事件的支持情况

    近日购入一部微软Lumia 640手机,目的主要就是为了测试年中开发完成的响应式移动web项目,同时也为了将来升级win10 mobile系统.由于我们的项目目前只考虑支持IOS与Android系统, ...

  3. onunload与onbeforeunload事件解析 标签: 浏览器 2017-04-10 09:46 45人阅读 评论(0)

    注:只测试了chrome和IE浏览器的表现情况 onunload事件 //JS Document window.onunload = onunload_message; function onunlo ...

  4. JS事件 卸载事件 当用户退出页面时(页面关闭、页面刷新等),触发onUnload事件,同时执行被调用的程序。注意:不同浏览器对onunload事件支持不同。

    卸载事件(onunload) 当用户退出页面时(页面关闭.页面刷新等),触发onUnload事件,同时执行被调用的程序. 注意:不同浏览器对onunload事件支持不同. 如下代码,当退出页面时,弹出 ...

  5. JS之onunload、onbeforeunload事件详解

    简介 onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过 window.onunload来调用.区别在于onbeforeunload在o ...

  6. 160503、onunload、onbeforeunload事件详解

    最近项目中做到一个功能:在上传页面用户开始上传文件之后用户点击任意跳转都需要弹出提示层进行二次确定才允许他进行跳转,这样做的目的是为了防止用户的错误操作导致这珍贵的UGC 流失(通常用户在一次上传不成 ...

  7. onunload、onbeforeunload事件详解--zhuan

    最近项目中做到一个功能:在上传页面用户开始上传文件之后用户点击任意跳转都需要弹出提示层进行二次确定才允许他进行跳转,这样做的目的是为了防止用户的错误操作导致这珍贵的UGC 流失(通常用户在一次上传不成 ...

  8. Spring中ApplicationContext对事件的支持

    Spring中ApplicationContext对事件的支持   ApplicationContext具有发布事件的能力.这是因为该接口继承了ApplicationEventPublisher接口. ...

  9. Javascript检测浏览器对CSS属性的支持 /* supports */

    //检测浏览器对CSS属性的支持 supports = (function() { var div = document.createElement('div'), vendors = 'Khtml ...

随机推荐

  1. python 单元测试

    http://blog.csdn.net/five3/article/details/7104466

  2. Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条

    Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Ap ...

  3. 电容式触摸控制器PCB布局

    在目前市场上可提供的PCB(印刷电路板)基材中,FR4是最常用的一种.FR4是一种玻璃纤维增强型环氧树脂层压板,PCB可以是单层或多层. 在触摸模块的尺寸受限的情况下,使用单层PCB不是总能行得通的, ...

  4. Pots(bfs)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8266   Accepted: 3507   Special Judge D ...

  5. gif动画问题

    iOS没有自带支持显示gif动画的功能,  用UIImageView的animationImage虽然可以实现图片动画, 当毕竟不方便. http://blog.stijnspijker.nl/200 ...

  6. 汇编学习笔记(7)call和ret指令

    ret和retf CPU执行ret指令时进行以下两步操作: (IP)=((ss)*16+(sp)) (sp)=(sp)+2 这相当于pop IP CPU执行retf指令时进行以下四步操作: (IP)= ...

  7. bzoj 1089 [SCOI2003]严格n元树(DP+高精度)

    1089: [SCOI2003]严格n元树 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1250  Solved: 621[Submit][Statu ...

  8. tyvj P1431 [Tyvj Jan]分配任务(最大流)

    P1431 [Tyvj Jan]分配任务 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述      随着tyvj发展越来越大,管理员的任务越来越重,如何合理的 ...

  9. UVAlive2531 The K-League(最大流)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33451 [思路] 最大流. 大体思路是枚举每个队伍,最大流判断是否 ...

  10. (转)【C++ STL】细数C++ STL 的那些事 -- priority_queue(优先队列)

    装载自http://blog.csdn.net/tianshuai1111/article/details/7652553 一,概述 priority_queue是拥有权值观念的queue,它允许加入 ...