需求:在h5游戏页面,当用户首次点击后退按钮、退出当前页面之前,弹出自定义的弹窗提示。
beforeunload/unload
beforeunload/unload 的触发
当离开当前页面时,会触发 beforeunload;比如以下操作:
- 关闭浏览器窗口
- 点击返回、前进、主页,刷新页面
- window.open(),location.href=’’,submit提交表单,等
beforeunload 与 unload 触发时间的区别:beforeunload
是在没新页面跳转之前触发,此时新页面的新资源请求尚未发出;unload
是在旧资源已经卸载,新页面的新资源请求已经发出,但新页面还没替换旧页面的时候触发的;
总结: beforeunload 在 unload 之前触发。
beforeunload 与 unload 的使用示例:
|
|
此时,当用户点击触发页面后退时,浏览器会弹出默认弹窗提示。
这个默认的弹窗,是浏览器内置的事件;该事件并未对开发者提供可以自定义弹窗的交互接口,开发者不能自定义。
因此,beforeunload/unload
不能实现后退时弹窗自定义弹窗的需求。
pushState/popstate
history.pushState()
方法向浏览器历史添加了一个状态。history.pushState(state object, title, URL)
,带有三个参数:
一个状态对象,一个标题(现在被忽略了),以及一个可选的URL地址。详见 History.pushState()
popstate 事件的触发:
点击后退、前进按钮(或者在JavaScript中调用 history.back()、history.forward()、history.go()方法);
调用 history.pushState() 或者 history.replaceState() 不会触发popstate事件
注意点:
- History.pushState()可以改变当前 url,但不会刷新页面;
- 点击后退离开当前页面,当前的 url 要发生变化(触发hash值的变化);
- hash值的变化不会刷新当前页面,会触发popstate事件
页面后退自定义弹窗
基本思路:
- 进入页面,当前 url 为:
a.com/game.html
- 进入页面后,立即 pushState 一个新链接(追加了hash值)到 history 中,改变了链接但页面没刷新,此时 url 为
a.com/game.html#leaveStatus
;同时将变量leaveStatus = 1
; - 用户点击了后退,此时 url 后退到
a.com/game.html
,但页面未刷新;同时触发了 popstate 事件; - 触发了 popstate 事件,若此时
leaveStatus = 1
,则显示自定义弹窗
具体实现代码(新增了cookie设置,一天内不再弹窗):
|
|
the end 。