HTML5小游戏移动端需分场景拦截退出:Android用popstate+pushState模拟返回栈并弹自定义模态框;iOS手势无法拦截,应预留安全区并引导自动存档续玩;onbeforeunload仅对刷新有效且文案受限。
HTML5小游戏在移动端容易因误触浏览器返回键、系统返回手势或页面刷新按钮而意外退出,这不是代码 bug,而是交互边界没被主动控制——浏览器本身不提供「游戏模式」,必须靠开发者手动拦截关键事件并引导用户确认。
监听 window.onbeforeunload 仅对刷新/关闭标签页有效
这个事件能拦截用户主动刷新、关闭标签页或输入新 URL 的行为,但对 Android 返回键、iOS 底部返回手势、PWA 离线后点击系统返回等完全无效。它只在「页面即将卸载」时触发,且现代浏览器(Chrome 80+、Safari 14.5+)已限制其弹窗文案,只能显示默认提示语,不能自定义内容。
- 仅适用于桌面端或部分 PWA 场景下的刷新防护
- 移动端返回键触发时,
onbeforeunload不会执行 - 若返回值为
falsy(如return false),现代浏览器直接忽略;需返回任意非空字符串(如return "游戏未保存,确定要离开?"),但实际显示文案由浏览器决定
Android 返回键拦截必须用 popstate + history.pushState
移动端 WebView 或 Chrome for Android 中,物理返回键默认触发 history.back()。想拦截它,得先让页面历史栈“变厚”:在游戏启动时调用一次 history.pushState,再监听 popstate 事件,在回调里阻止默认跳转,并弹出确认框。
- 首次进入游戏时执行:
history.pushState({ game: true }, "") - 监听:
window.addEventListener("popstate", handleBack) -
handleBack中调用event.preventDefault()无效,真正起作用的是在回调里再次pushState并弹窗;否则第二次按返回键仍会退到上一页 - 注意:PWA 安装后运行在 standalone 模式下,返回键可能直接退出应用,此时该方法失效,需配合
beforeinstallprompt提示用户添加到主屏幕并说明操作习惯
用 confirm() 弹窗风险高,推荐自定义 DOM 模态框
直接在 popstate 回调里调用 confirm("退出游戏?") 会导致 UI 卡顿、动画中断,且部分 Android 浏览器(如 Samsung Internet)会静默吞掉该弹窗。更可靠的做法是用绝对定位的
模拟确认层,禁用背景滚动,聚焦确认按钮。
立即学习“前端免费学习笔记(深入)”;