Window:beforeunload 事件
噹噹前視窗、所含文件和關聯資源即將被解除安裝時,會觸發 beforeunload 事件。此時文件仍然可見,並且事件仍然可以取消。
此事件的主要用例是觸發瀏覽器生成的確認對話方塊,詢問使用者是否真的想離開頁面,例如當他們嘗試關閉或重新載入頁面,或導航到其他地方時。這旨在幫助防止未儲存資料的丟失。
可以透過以下方式觸發對話方塊:
- 呼叫事件物件的
preventDefault()方法。 - 將事件物件的
returnValue屬性設定為非空字串值或任何其他 真值。 - 從事件處理函式返回任何真值,例如
return "string"。請注意,這僅在函式透過onbeforeunload屬性(而不是addEventListener()方法)附加時才有效。此行為在現代版本的 Firefox、Safari 和 Chrome 中是一致的。
後兩種機制是遺留特性;最佳實踐是透過在事件物件上呼叫 preventDefault() 來觸發對話方塊,同時設定 returnValue 以支援遺留情況。
語法
在諸如 addEventListener() 之類的方法中使用事件名稱,或設定事件處理程式屬性。
addEventListener("beforeunload", (event) => { })
onbeforeunload = (event) => { }
事件型別
一個 BeforeUnloadEvent。繼承自 Event。
用法說明
為了在使用者關閉或導航選項卡時顯示對話方塊,beforeunload 事件處理函式應在事件物件上呼叫 preventDefault()。您應該注意,現代實現
- 需要 粘性啟用 才能顯示對話方塊。換句話說,只有當框架或任何嵌入框架接收到使用者手勢或使用者互動時,瀏覽器才會顯示對話方塊。如果使用者從未與頁面互動,那麼就沒有使用者資料需要儲存,因此對話方塊沒有合法用例。
- 只在顯示的對話方塊中顯示一個通用的瀏覽器指定字串。這不能由網頁程式碼控制。
beforeunload 事件存在一些問題:
-
它並非總是可靠地觸發,尤其是在移動平臺上。例如,在以下場景中,
beforeunload事件根本不會觸發:- 移動使用者訪問您的頁面。
- 使用者隨後切換到不同的應用程式。
- 稍後,使用者從應用程式管理器關閉瀏覽器。
注意:建議使用
visibilitychange事件作為更可靠的自動應用程式狀態儲存訊號,以避免上述問題。有關詳細資訊,請參閱 不要丟失使用者和應用程式狀態,使用頁面可見性。 -
在 Firefox 中,
beforeunload與 前進/後退快取 (bfcache) 不相容:即,如果頁面具有beforeunload監聽器,Firefox 將不會將它們放入 bfcache,這會影響效能。
因此,建議開發人員僅在使用者有未儲存的更改時監聽 beforeunload,以便可以使用上述對話方塊警告他們即將丟失資料,並在不需要時再次移除監聽器。節制地監聽 beforeunload 可以最大限度地減少對效能的影響。
事件處理程式別名
除了 Window 介面,事件處理程式屬性 onbeforeunload 也可在以下目標上使用:
示例
在以下示例中,我們有一個 HTML 文字 <input>,用於表示可能已更改並需要儲存的一些資料:
<form>
<input type="text" name="name" id="name" />
</form>
我們的 JavaScript 將 input 事件監聽器附加到 <input> 元素,以監聽輸入值的更改。當值更新為非空值時,beforeunload 事件監聽器將附加到 Window 物件。
如果值再次變為空字串(即值被刪除),則 beforeunload 事件監聽器將再次刪除——如上文 使用說明 中所述,當沒有未儲存資料需要警告時,應刪除監聽器。
當用戶關閉或導航選項卡時,beforeunload 事件處理函式會呼叫 event.preventDefault() 來觸發警告對話方塊。我們還在處理函式中包含了 event.returnValue = true,以便任何不支援 event.preventDefault() 機制的瀏覽器仍能正確執行演示。
const beforeUnloadHandler = (event) => {
// Recommended
event.preventDefault();
// Included for legacy support, e.g. Chrome/Edge < 119
event.returnValue = true;
};
const nameInput = document.querySelector("#name");
nameInput.addEventListener("input", (event) => {
if (event.target.value !== "") {
window.addEventListener("beforeunload", beforeUnloadHandler);
} else {
window.removeEventListener("beforeunload", beforeUnloadHandler);
}
});
當 <input> 值非空時,如果您嘗試關閉、導航或重新載入頁面,瀏覽器會顯示警告對話方塊。試試看:
規範
| 規範 |
|---|
| HTML # event-beforeunload |
| HTML # handler-window-onbeforeunload |
瀏覽器相容性
載入中…
另見
BeforeUnloadEvent介面- 相關事件
- Page Lifecycle API 提供了更多有關處理 Web 應用程式中頁面生命週期行為的有用指南。