监控浏览器回退操作
-
背景
业务需要在用户离开当前页时进行提示保存数据。
-
实现方案
-
监听beforeunload,此事件在浏览器窗口关闭或者刷新时会触发,能够涵盖一部分用户操作,这是浏览器原生支持的事件。会弹出一个确认框,点击确认继续操作,点击取消中断操作。
-
使用H5提供的history接口。
-
实现机制,在点击浏览器返回按钮时,会触发 history.popState 事件,解决方式就是监听 popState 事件。
-
但是当点击浏览器后退按钮时,浏览器在触发 popState 事件后会直接返回上一页历史记录,不会给你丝毫反应时间,想用 alert 阻塞都不行。那既然这样不行那怎么办呢?
-
解决办法就是在进入页面时,先把历史记录改了,置为 null,代码如下所示:
history.pushState(null, null, document.URL);
关于 pushState 的具体使用详见 MDN,总之,这行代码把浏览器的回退目标重订在了本页面,这样的话在点击浏览器回退按钮时,还是会停留在当前页面,给用户的感觉就是还没走呢。并且这时候也能做一些提示操作。 -
监听 popState 事件
window.addEventListener('popstate', doSomething, false);
在 callback doSomething 中进行操作。
-
注意:在对用户提示以后,用户点击确定,一定要进行回退,那么该怎么办呢?这时候又用到了 history 的第二个api history.go(Step),具体使用见MDN
history.go(-2) 或 history.go(-1)
-
为什么是 -2 或者 -1 呢?首先正负问题,因为正数是前进几个页面,负数是回退页面,咱们是进行回退,所以是负数。
-
其次为啥是 -2 或 -1 ?首先是因为我们在一进入页面时调用 pushState 增加了一个本页面占位记录,所以想回到真实的页面,则必须跳过这个占位页面。当点击浏览器回退按钮时,它会直接去掉一条占位记录,属于浏览器默认行为,所以想回到真实记录的页面,只需要再回退一条就行,即 -1 ;而有些情况下,需要点击自定义的返回按钮,咱们自己写的返回按钮就无法自动触发回退页面,所以需要跳过两个页面到达真实回退页面,故需要 -2;
-
-
记住最后在组件卸载时,需要解绑事件
完结,撒花