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 应用程序中页面生命周期行为的有用指南。