各瀏覽器對 onbeforeunload 事件的支援與觸發條件實現有差異

來源:互聯網
上載者:User
文章目錄
  • 知識庫
  • 相關問題
 
問題描述

一般情況下,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:">調用 mailto: 偽協議</a><br /><a 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 事件被頻繁觸發。

參見知識庫
  • ...
相關問題
  • BT9012: IE 的 external 對象提供的方法是 IE 特有的
  • BX2032: 某些情況下瀏覽器不按照 "target" 屬性所指目標開啟協議連結
  • BX2003: 特定的 URL 偽協議需安裝提供該協議的特定軟體才有效
  • BX9052: IE Opera 支援使用 window.navigate 方法控制頁面跳轉
測試環境
作業系統版本: 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

本篇文章正在公測階段,錯誤在所難免,歡迎大家提出寶貴的意見和建議。

 

轉載於:http://w3help.org/zh-cn/causes/BX2047

 

 

測試頁面代碼:

 

<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><script>window.onbeforeunload=function(){return "請點擊取消留在此頁";}</script><body>請手工關閉當前瀏覽器視窗。<br/>請手工單擊後退,前進,重新整理,或首頁按鈕。<br/>請手工在地址欄輸入其他頁面地址或從收藏夾、記錄中將頁面導航其他網站。<br/><a href="http://www.google.com" id="A">點擊一個連結到新頁面</a><br /><button onclick="try{document.getElementById('A').click()}catch(e){alert('不支援此方法')}">調用 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><br /><a href="javascript:">調用 javascipt: 偽協議</a><br /><a href="mailto:">調用 mailto: 偽協議</a><br /><a href="custom:">調用自訂偽協議</a></body></html>

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.