各浏览器对 onbeforeunload 事件的支持与触发条件实现有差别

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

 

标准参考

无。html

问题描述

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

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

形成的影响

此问题不会形成大问题,但会致使不友好的提示出现,稍微影响用户操做体验。web

受影响的浏览器

全部浏览器  

问题分析

onbeforeunload 事件是非 W3C DOM-Event 标准事件,它属于 BOM (Browser Object Model) 范畴。到如今为止 BOM 尚未被标准化,它由各个浏览器厂商制定,所以会有实现差别。api

时至今日,HTML5 规范草案中已经开始标准化 BOM,遗憾的是 onbeforeunload 事件的触发条件尚未在草案中做出详细说明。浏览器

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

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

根据 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

相关文章
相关标签/搜索