Window:beforeunload 事件

可用性有限

此特性不是基線特性,因為它在一些最廣泛使用的瀏覽器中不起作用。

噹噹前視窗、所含文件和關聯資源即將被解除安裝時,會觸發 beforeunload 事件。此時文件仍然可見,並且事件仍然可以取消。

此事件的主要用例是觸發瀏覽器生成的確認對話方塊,詢問使用者是否真的想離開頁面,例如當他們嘗試關閉或重新載入頁面,或導航到其他地方時。這旨在幫助防止未儲存資料的丟失。

可以透過以下方式觸發對話方塊:

  • 呼叫事件物件的 preventDefault() 方法。
  • 將事件物件的 returnValue 屬性設定為非空字串值或任何其他 真值
  • 從事件處理函式返回任何真值,例如 return "string"。請注意,這僅在函式透過 onbeforeunload 屬性(而不是 addEventListener() 方法)附加時才有效。此行為在現代版本的 Firefox、Safari 和 Chrome 中是一致的。

後兩種機制是遺留特性;最佳實踐是透過在事件物件上呼叫 preventDefault() 來觸發對話方塊,同時設定 returnValue 以支援遺留情況。

語法

在諸如 addEventListener() 之類的方法中使用事件名稱,或設定事件處理程式屬性。

js
addEventListener("beforeunload", (event) => { })

onbeforeunload = (event) => { }

事件型別

一個 BeforeUnloadEvent。繼承自 Event

用法說明

為了在使用者關閉或導航選項卡時顯示對話方塊,beforeunload 事件處理函式應在事件物件上呼叫 preventDefault()。您應該注意,現代實現

  • 需要 粘性啟用 才能顯示對話方塊。換句話說,只有當框架或任何嵌入框架接收到使用者手勢或使用者互動時,瀏覽器才會顯示對話方塊。如果使用者從未與頁面互動,那麼就沒有使用者資料需要儲存,因此對話方塊沒有合法用例。
  • 只在顯示的對話方塊中顯示一個通用的瀏覽器指定字串。這不能由網頁程式碼控制。

beforeunload 事件存在一些問題:

  • 它並非總是可靠地觸發,尤其是在移動平臺上。例如,在以下場景中,beforeunload 事件根本不會觸發:

    1. 移動使用者訪問您的頁面。
    2. 使用者隨後切換到不同的應用程式。
    3. 稍後,使用者從應用程式管理器關閉瀏覽器。

    注意:建議使用 visibilitychange 事件作為更可靠的自動應用程式狀態儲存訊號,以避免上述問題。有關詳細資訊,請參閱 不要丟失使用者和應用程式狀態,使用頁面可見性

  • 在 Firefox 中,beforeunload前進/後退快取 (bfcache) 不相容:即,如果頁面具有 beforeunload 監聽器,Firefox 將不會將它們放入 bfcache,這會影響效能。

因此,建議開發人員僅在使用者有未儲存的更改時監聽 beforeunload,以便可以使用上述對話方塊警告他們即將丟失資料,並在不需要時再次移除監聽器。節制地監聽 beforeunload 可以最大限度地減少對效能的影響。

事件處理程式別名

除了 Window 介面,事件處理程式屬性 onbeforeunload 也可在以下目標上使用:

示例

在以下示例中,我們有一個 HTML 文字 <input>,用於表示可能已更改並需要儲存的一些資料:

html
<form>
  <input type="text" name="name" id="name" />
</form>

我們的 JavaScript 將 input 事件監聽器附加到 <input> 元素,以監聽輸入值的更改。當值更新為非空值時,beforeunload 事件監聽器將附加到 Window 物件。

如果值再次變為空字串(即值被刪除),則 beforeunload 事件監聽器將再次刪除——如上文 使用說明 中所述,當沒有未儲存資料需要警告時,應刪除監聽器。

當用戶關閉或導航選項卡時,beforeunload 事件處理函式會呼叫 event.preventDefault() 來觸發警告對話方塊。我們還在處理函式中包含了 event.returnValue = true,以便任何不支援 event.preventDefault() 機制的瀏覽器仍能正確執行演示。

js
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

瀏覽器相容性

另見