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行爲,但直觀上來講,是咱們刪除了一條歷史記錄