使用原生JS监听浏览器的前进后退事件
对于前端路由,比如React Router的应该都知道,一般路由有2种模式:hash路由和history路由,为了实现路由变化的监听,hash路由使用了onhashchange事件,而history路由使用了onpopstate事件,在这2种路由路由模式下,用对应的事件不仅可以监听到路由改变,同样也可以监听到浏览器的前进后退(本质上也是路由改变),但是前提条件就是需要得使用路由模式,如果是常规的页面跳转比如a.html跳转到了b.html,然后在b.html点回退到a.html,我怎么确定a.html是由别的页面回退前进才展示的,还是刷新导致的呢?接下来我们一步一步开始分析。
首先,我们需要知道页面是否展示了,通过监听onpageshow事件,我们可以知道页面展示了,相比onload事件,onpageshow会在每一次刷新页面和页面展示时调用,但是onload事件只会在刷新页面时调用,而回退和前进不一定会触发页面刷新,我们可以通过以下代码测试:
a.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>页面A</title> </head> <body> 我是页面A <script> window.onpageshow = function() { console.log('page 1 show'); } window.onload = function() { console.log('page 1 load') } </script> <a href="b.html">跳转 b</a> </body> </html>
b.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>页面B</title> </head> <body> 我是页面B <script> window.onpageshow = function() { console.log('page b show'); } window.onload = function() { console.log('page b load') } </script> </body> </html>
现在我们已经可以监听到页面的每一次展示,接下来判断页面的展示是因为刷新还是回退前进导致的呢?performance.navigation.type可以用于判断网页来源类型,其取值有以下几种:
performance.navigation.TYPE_NAVIGATE
通过点击链接、地址栏输入、表单提交、脚本操作等方式加载
performance.navigation.TYPE_RELOAD
通过“重新加载”按钮或location.reload()方法加载
performance.navigation.TYPE_BACK_FORWARD
通过“前进”或“后退”按钮加载
performance.navigation.TYPE_RESERVED
任何其他原因导致的加载
所以我们要确定页面展示是否因为“回退”或“前进”导致的,只需要看performance.navigation.type是不是等于performance.navigation.TYPE_BACK_FORWARD即可,代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>页面A</title> </head> <body> 我是页面A <div id="status"></div> <script> window.onpageshow = function() { const navigation = window.performance.navigation; if (navigation.type === navigation.TYPE_BACK_FORWARD) { document.getElementById('status').innerText = '回退或前进'; } } window.onload = function() { console.log('page 1 load') } </script> <a href="b.html">跳转 b</a> </body> </html>
- 支付宝
- 微信