PC浏览器返回等于从新进入上一个页面,会触发刷新动做,而微信不会。也就是困扰我多时的微信返回不刷新。chrome
大概再2017年初和2016末(大概也是从那个时候我开始作微信公众号),还能够经过在sessionStorage中记录刷新标志,让上一个页面根据标识刷新。也就是说当时微信返回仍是会触发渲染事件的(具体是什么事件也不清楚,由于当时没有深究,可是确实是触发了componentDidMount)。浏览器
可是某个时刻起,这种方法也再也不有效了,说明经过storage记录须要刷新标志是彻底失效的了。微信
另外能够发现,上一个页面会保持上一次操做的状态,而且不会再有静态资源的请求,不会触发load事件。那也能够这么理解,在微信中的页面跳转,其实更相似于浏览器中的打开新标签页。因此上一个页面的内容没有被销掉,而是会保持你跳走前的状态。因此咱们不少页面会有点击返回可是loading仍是在转的现象。session
由此,我想到了第一个检查他是否返回的方法——监听页面的visibilitychange事件。由于PC浏览器中若是标签切换或者是浏览器缩略,其可见性改变的时候,都会触发该事件。app
有兴趣的能够打开控制台输入如下代码,看看有什么不一样。ide
window.addEventListener('visibilitychange', function () { console.log(document.hidden) });
总之我先尝试了如下代码:fetch
let isPageBack = false; window.addEventListener('visibilitychange', function () { if(document.hiden){ isPageBack = true } else if ( isPageBack ) { fetch('/data') //由于visibilitychange事件中alert能够看到被模拟器禁了,因此就改用改了fetch本身的接口,经过查看日志检查是否触发 } });
尝试以后发现该事件并无被触发。疑惑之余,我尝试了chrome手机浏览器,发现一样,该事件没有被触发。url
另外,由于好奇若是app压后台会不会触发该事件,因此尝试这段代码↓,结果发现即便压后台页面也不会被挂起。日志
setInterval(function () { var p = document.createElement('p'); p.appendChild(document.createTextNode(`${Date.now()}`)); document.body.appendChild(p); }, 1000)
与visibilitychange相似的还有pageshow和pagehide事件。code
pageshow事件触发点是 a session history entry is being traversed to. 同时根据MDN的介绍在back/forward时也会被触发
因而我改了改代码
let isPageBack = false; window.addEventListener('pageshow', function () { if (isPageBack ) fetch('/data') }) window.addEventListener('pagehide', function () { isPageBack = true })
竟然意外的能行,,,
pageshow和pagehide事件能够被监听到。返回页能够经过页面是否隐藏过知道是不是返回回来的。
history能够修改历史记录或url主要是 history.pushState 和 history.replaceState 。
使用pushState 等于多推一条历史记录,replaceState 等于修改了历史记录,另外咱们要知道reload是不计入历史记录的。
理论上来讲若是使用pushState修改url,那么页面访问就会像这样 A -> A1 -> B
当B返回A1时就会触发 popstate 事件。在popstate事件里面能够作一些自定义的事情。
这里用了代码
var state = { date: Date.now() }; window.history.pushState(state, 'csb'); window.addEventListener('popstate', function (event) { if(event.state) location.reload() })
检查history时,能够看到state里面有一个key是date的时间戳,同时历史记录的长度+1。
可是使用pushState会增长历史记录,会致使同一个页面须要返回好几回才能退出去,不过能够利用他作返回退出公众号
window.history.pushState({}, 'csb'); window.addEventListener('popstate', function (event) { if (event.state) { wx.ready(function () { wx.closeWindow(); }); } });
可是由于replaceState不会增长历史记录,因此利用它这样返回刷新页面
history.replaceState(null, null, '#'); window.addEventListener('popstate', function (event) { self.location.reload(); })
另外若是要若是A->B->C,而C返回时想要直接返回A能够这样
B页面:
history.replaceState(null, null, '/c'); //将url替换成C,这样跳转到C页面等于被转变成了reload行为,但直观上来讲,是咱们删除了一条历史记录