onbeforeunload生效需满足用户交互后触发且isdirty为true,e.preventdefault()与e.returnvalue必须同时设置;spa路由跳转需用路由守卫拦截,不可依赖该事件发请求,应配合localstorage自动存草稿。

onbeforeunload 不是“怎么做提示”,而是“怎么让浏览器允许弹提示”——它只在满足特定条件时才可能生效,且你无法控制提示文案。
为什么加了监听却从不弹窗
常见失效根本不是代码写错,而是没触发浏览器的“脏状态”认定:
- 页面加载后没任何用户交互(点击、输入、拖动等),直接关闭或刷新 →
beforeunload事件仍会触发,但浏览器拒绝弹窗 -
event.returnValue赋值为空字符串、null或undefined→ Chrome/Firefox/Safari 全部忽略 - 在 Vue/React 组件挂载时注册但没卸载,导致多次绑定 → 部分浏览器静默丢弃重复 handler
- 用
router.push()或history.pushState()导航 → 这类 JS 主动跳转不触发beforeunload
必须配合用户操作标记“已变更”
核心逻辑不是监听离开,而是跟踪是否真有未保存内容。示例中用 isDirty 布尔值是最轻量可靠的方式:
let isDirty = false;
// 用户修改表单时标记
document.addEventListener('input', () => { isDirty = true; });
document.addEventListener('change', () => { isDirty = true; });
// 提交成功后重置
document.querySelector('form').addEventListener('submit', (e) => {
// 假设保存成功
isDirty = false;
});
window.addEventListener('beforeunload', (e) => {
if (isDirty) {
e.preventDefault();
e.returnValue = '确认要离开?未保存的内容将丢失。'; // 仅兼容旧 IE,现代浏览器无视该字符串
}
});
注意:e.preventDefault() 和 e.returnValue 必须同时存在,缺一不可;返回字符串不能是空格或纯空白符。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
SPA 路由跳转需手动拦截
Vue Router 或 React Router 的内部导航不会触发 beforeunload,必须用框架提供的守卫:
- Vue Router:在
beforeEach或beforeRouteLeave中检查isDirty,调用next(false)阻止跳转 - React Router v6+:使用
useBlocker,传入判断函数() => isDirty - 切勿在路由守卫里试图手动触发
beforeunload——window.dispatchEvent(new Event('beforeunload'))无效
别指望 unload 做清理或发请求
unload 事件在页面冻结 UI 后才触发,此时:
-
fetch()、XMLHttpRequest几乎必然失败,连navigator.sendBeacon()在部分 Safari 版本中也不稳定 -
alert、confirm、setTimeout全部无效,用户看不到任何反馈 - 唯一安全操作是清除定时器、移除监听器、释放 Worker 引用等极轻量同步动作
真正需要保底提交数据,请用 localStorage 实时缓存 + 定期自动保存,而不是赌 beforeunload 和 unload 的执行时机和成功率。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










