pageshow事件必须用window.addeventlistener绑定,不可内联在body上;event.persisted为true表示从bfcache恢复(如后退/前进),false为首次加载或刷新;需结合navigation type或框架路由钩子避免误判。

onpageshow 不能写在 上
直接在 里写属性,基本无效。因为 pageshow 是全局页面生命周期事件,触发时机早于 DOM 解析完成, 标签此时可能还没挂载;而且该事件不冒泡,内联写法根本收不到。Chrome 11+、Firefox 5+、Safari 实测均无法稳定触发。
event.persisted 是唯一可靠判断依据
必须用 window.addEventListener("pageshow", ...) 绑定,并从事件对象里读 event.persisted:
-
event.persisted === true→ 页面从 bfcache 恢复,典型场景就是用户点了浏览器后退/前进按钮(或执行了history.back()/history.forward()) -
event.persisted === false→ 页面是首次加载、刷新、或新标签页打开
注意:jQuery 里要写成 event.originalEvent.persisted,否则取不到。
常见误判场景和应对方式
只靠 pageshow + persisted 还不够,容易踩坑:
- 用户手动修改 URL 后点后退,
pageshow仍会触发且persisted为true,但实际不是“纯后退”,需结合performance.getEntriesByType("navigation")查最近一次导航的type字段是否为"back_forward" - SPA(如 React Router)接管了路由,原生
pageshow仍会触发,但业务逻辑应优先走路由库的useEffect或onPopState钩子,避免和框架状态冲突 -
pageshow在页面恢复时立即触发,但 DOM 可能尚未就绪,若需操作元素,得配合document.readyState === "complete"或DOMContentLoaded判断
别指望 onbeforeunload 或 popstate 替代
这几个事件目的不同,混用会出问题:
-
onbeforeunload是离开前触发,不能用来判断“怎么来的”,它只管“要走了” -
popstate只响应pushState/replaceState触发的导航,对普通链接跳转、刷新、后退按钮(未调用 history API 的)不触发 -
pagehide虽然配对,但它只告诉你“要藏了”,不提供来源信息,event.persisted在这里同样关键,但用途是保存状态,不是判断入口
真正要区分“是不是后退/前进进来的”,window.pageshow + event.persisted 是目前最直接、最广泛支持的路径,其他方案都是补丁而非替代。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











