各瀏覽器對 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

相關文章
相關標籤/搜索