關(guān)于history的一點心得

瀏覽器上的window.history就是記錄頁面的歷史記錄的,在瀏覽器上打印history對象,會有如下:

History {pushState: ?, replaceState: ?, length: 7, scrollRestoration: "auto", state: null}

history.length

length是指當(dāng)前瀏覽過多少個頁面,無論你是執(zhí)行后退還是前進(jìn)一頁,history都是不變的,除非在當(dāng)前頁面新打開一個鏈接,那么history就會加一。

history.pushState

history.pushState(State,Title,Url),不跳轉(zhuǎn),新增一條歷史記錄,當(dāng)前頁面的url會變成Url,但是不會刷新當(dāng)前頁面,如果此時新打開一個頁面,后退會去到Url鏈接,但頁面內(nèi)容還是url的內(nèi)容,再后退就會去到url鏈接,內(nèi)容不變,就是url的內(nèi)容。
需要注意的是,history.pushState的Url不能跨域,否則會報錯。

history.replaceState

history..replaceState(State,Title,Url),不跳轉(zhuǎn),修改瀏覽歷史中當(dāng)前紀(jì)錄,當(dāng)前頁面url的歷史記錄會被替換成指定的Url,當(dāng)前頁面的url會變成Url,直接替換掉原來的url,相當(dāng)于原來的url已經(jīng)不存在,但是不會刷新當(dāng)前頁面,如果此時新打開一個頁面,后退會去到Url鏈接,但頁面內(nèi)容會改變成Url的內(nèi)容,再后退就沒有可后退的鏈接了。
需要注意的是,history.replaceState的Url不能跨域,否則會報錯。

location.replace

location.replace(url) 會跳轉(zhuǎn)至指定頁面,當(dāng)前頁面url的歷史記錄不會保留,相當(dāng)于替換了當(dāng)前的歷史記錄

location.href

location.href:跳轉(zhuǎn)至指定頁面,當(dāng)前頁面url的歷史記錄會保留

window.onpopstate

每當(dāng)同一個文檔的瀏覽歷史(即history對象)出現(xiàn)變化時,就會觸發(fā)popstate事件。僅僅調(diào)用pushState方法或replaceState方法 ,并不會觸發(fā)該事件,只有用戶點擊瀏覽器倒退按鈕和前進(jìn)按鈕,或者使用JavaScript調(diào)用back、forward、go方法時才會觸發(fā)。使用的時候,可以為popstate事件指定回調(diào)函數(shù)。這個回調(diào)函數(shù)的參數(shù)是一個event事件對象,它的state屬性指向pushState和replaceState方法為當(dāng)前URL所提供的狀態(tài)對象(即這兩個方法的第一個參數(shù)state)。如:

history.pushState({title:"login"}, "login", "/login");
window.onpopstate = function (event) {
   if(event.state) {
        var state = event.state.title;
        switch(state) {
           case "login":.............;break;
           case "join" :.............;break;
        }
     }
};
// 或者
window.addEventListener("popstate", function(event){
    if(event.state) {
        var state = event.state.title;
        switch(state) {
           case "login":.............;break;
           case "join" :.............;break;
        }
     }
}, false);

上面代碼中的event.state,就是通過pushState和replaceState方法,為當(dāng)前URL綁定的state對象。這個state對象也可以直接通過history對象讀取history.state。

實踐

最近做的一個需求是這樣的:先由中轉(zhuǎn)頁a跳去目標(biāo)頁面b,按回退按鈕,跳去中間后臺配置頁面b1,再按回退按鈕跳去中間后臺配置頁面b2,以此下去,只到跳轉(zhuǎn)完所有后臺配置的頁面,最終跳回目標(biāo)頁面b,再按返回退出所有頁面。

用history來解釋的話就是:

a->b->back->a->b1->back->b2->...->back->b->back->退出

用上面的知識來解決就是

a->b,在a頁面,獲取跳轉(zhuǎn)url的b頁面鏈接,替換參數(shù),改變a鏈接成a*,即將a的歷史記錄修改成a*,執(zhí)行
history.replaceState(null, document.title, a*);window.location.href = b;
回退,此時到a*,獲取后臺配置,執(zhí)行
window.location.href = b1;
回退,此時到a*,獲取后臺配置,執(zhí)行
window.location.href = b2;
....
后退回到a*,最后回到b,執(zhí)行
window.location.replace(b);
再后退,退出頁面

以上就是利用history和location解決的一個簡單示例,其他的應(yīng)用還可以是改變一個頁面的url而不用刷新頁面等。

外篇

pageshowpagehide 事件

手機(jī)上的瀏覽器有一個特性,名叫“往返緩存”(back-forward cache,或bfcache),可以在用戶使用瀏覽器的“后退”和“前進(jìn)”按鈕時加快頁面的轉(zhuǎn)換速度。這個緩存中不僅保存著頁面數(shù)據(jù),還保存了DOM和JavaScript的狀態(tài);實際上是將整個頁面都保存在了內(nèi)存里。如果頁面位于bfcache中,那么再次打開該頁面就不會觸發(fā)load事件。盡管由于內(nèi)存中保存了整個頁面的狀態(tài),不觸發(fā)load事件也不應(yīng)該會導(dǎo)致什么問題,但為了更形象地說明bfcache的行為,F(xiàn)irefox還是提供了一些新事件。 第一個事件就是pageshow,這個事件在頁面顯示時觸發(fā),無論頁面是否來自bfcache。在重新加載頁面中,pageshow會在load事件觸發(fā)后觸發(fā);而對于bfcache中的頁面,pageshow會在頁面狀態(tài)完全恢復(fù)的那一刻觸發(fā)。
1)load 和 unload 事件監(jiān)聽web頁面的進(jìn)入和離開,一般用于頁面的首次加載、刷新和關(guān)閉等操作的監(jiān)聽;
2)pageshowpagehide 事件多用于監(jiān)聽瀏覽器的前進(jìn)和后退等。

pageshow和load區(qū)別:
pageshow 事件類似于 load 事件,load 事件在頁面第一次加載時觸發(fā), pageshow 事件在每次加載頁面時觸發(fā),即 load 事件在頁面從瀏覽器緩存中讀取時不觸發(fā)。

一般情況下,移動端瀏覽器會將當(dāng)前已訪問頁面存入緩存中,緩存中保存著頁面數(shù)據(jù),DOM和js的狀態(tài),前進(jìn)和后退操作時直接從瀏覽器緩存中讀取頁面內(nèi)容,而不進(jìn)行頁面刷新,所以監(jiān)聽前進(jìn)和后退操作時可用pageshow事件。

window.performance對象

performance.navigation.type是一個無符號短整型,接口呈現(xiàn)了如何導(dǎo)航到當(dāng)前文檔的信息。它有四種type類型:
1、TYPE_NAVIGATE (0):當(dāng)前頁面是通過點擊鏈接,書簽和表單提交,或者腳本操作,或者在url中直接輸入地址,type值為0。
2、TYPE_RELOAD (1):點擊刷新頁面按鈕或者通過Location.reload()方法顯示的頁面,type值為1:。
3、TYPE_BACK_FORWARD (2):頁面通過歷史記錄和前進(jìn)后退訪問時。type值為2。
4、TYPE_RESERVED (255): 任何其他方式,type值為255。
所以type為2可以作為頁面后退或者前進(jìn)時的一個判斷依據(jù)。

window.addEventListener('pageshow', (e) => {
  if (e.persisted || (window.performance && window.performance.navigation.type == 2)) {
    // 頁面后退或者前進(jìn)時刷新頁面
    location.reload()
  }

參數(shù)教程

  1. history.pushState無刷新改變url
  2. 原HTML5歷史狀態(tài)管理history API-pushState/replaceState與popstate事件
  3. pageshow和pagehide應(yīng)用場景
  4. 移動端返回強(qiáng)制刷新頁面pageshow事件persisted總為false解決方案
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容