深刻學習History對象管理瀏覽器會話歷史

History對象容許咱們操做瀏覽器會話歷史,即加載當前頁面的標籤頁窗口或frame窗口的訪問歷史。以前有同窗諮詢我如何實現攔截用戶跳轉頁面並強制用戶返回首頁後從新請求頁面,因而有了本篇博客的主題,本篇深刻介紹瀏覽器會話歷史的操做,在最後對比加載頁面的幾種不一樣方式,並提供一個實例給讀者把玩。javascript

屬性

  • History.lengthhtml

    只讀的,其值爲一個整數,標誌包括當前頁面在內的會話歷史中的記錄數量,好比咱們一般打開一個空白窗口,length爲0,再訪問一個頁面,其length變爲1。java

  • History.scrollRestorationweb

    容許web應用在會話歷史導航時顯式地設置默認滾動復原,其值爲auto或manual。瀏覽器

  • History.state緩存

    只讀,返回表明會話歷史堆棧頂部記錄的任意可序列化類型數據值,咱們能夠以此來區別不一樣會話歷史紀錄。安全

方法

  • History.back()函數

    返回會話歷史記錄中的上一個頁面,等價於window.history.go(-1)和點擊瀏覽器的後退按鈕。工具

  • History.forward()學習

    進入會話歷史記錄中的下一個頁面,等價於window.history.go(1)和點擊瀏覽器的前進按鈕。

  • History.go()

    加載會話歷史記錄中的某一個頁面,經過該頁面與當前頁面在會話歷史中的相對位置定位,如,-1表明當前頁面的上一個記錄,1表明當前頁面的下一個頁面。若不傳參數或傳入0,則會從新加載當前頁面;若參數超出當前會話歷史紀錄數,則不進行操做。

  • History pushState()

    在會話歷史堆棧頂部插入一條記錄,參數包括,任意可序列化的object對象數據(可選),頁面標題(可選),頁面URL(非空)。

    目前,Firefox忽略頁面標題參數。

  • History.replaceState()

    更新會話歷史堆棧頂部記錄信息,包括特定的任意可序列化的object對象數據(可選),頁面標題(可選),頁面URL。

值得注意的是,不管是replaceState()方法仍是pushState()方法,其更新或添加會話歷史記錄後,改變的只是瀏覽器關於當前頁面的標題和URL的記錄狀況,並不會刷新或改變頁面展現。

window.history

window的history是隻讀屬性,該屬性返回History對象的一個引用,支持咱們操做瀏覽器會話歷史記錄。

出於安全考慮,History對象不容許咱們經過JavaScript代碼訪問其餘會話歷史記錄中其餘頁面的URL,可是它容許咱們在不一樣頁面間進行導航。

onpopstate事件

HTML5中,提供history.pushState()和history.replaceState()方法,支持咱們添加或更新會話歷史記錄,另外還提供window.onpopstate事件支持咱們對該操做進行監聽。

pushState()

pushState()方法接收三個參數,一個state對象,一個頁面標題,一個URL:

  1. 狀態對象:

    1. 存儲新添會話歷史記錄的狀態信息對象,每次訪問該條會話時,都會觸發popstate事件,而且事件回調函數會接收一個參數,值爲該事件對象的複製副本;
    2. 狀態對象能夠是任何可序列化的數據,瀏覽器將狀態對象存儲在用戶的磁盤以便用戶再次重啓瀏覽器時能恢復數據;
    3. 一個狀態對象序列化後的最大長度是640K,若是傳遞數據過大,則會拋出異常。
  2. 頁面標題:

    1. 目前 ,該參數值會被忽略,暫不被使用,能夠傳入空字符串。
  3. 頁面URL:

    1. 此參數聲明新添會話記錄的入口URL;
    2. 在調用pushState()方法後,瀏覽器不會加載URL指向的頁面(在重啓瀏覽器後或許會加載新頁面 ),咱們能夠在popstate事件回調中處理頁面是否加載;
    3. 此URL必須與當前頁面URL同源,,不然會拋異常;其值能夠是絕對地址,也能夠是相對地址,相對地址會被基於當前頁面URL解析 獲得絕對地址;若其值爲空,則默認是當前頁面URL。

pushState()方法能夠改變URL地址欄,在會話歷史堆棧頂部插入一條新會話記錄,如:

var stateObj = { foo: "bar" };
    history.pushState(stateObj, "page 2", "bar.html");複製代碼

假如當前訪問頁面blog.codingplayboy.com,則執行以上js代碼後,瀏覽器地址欄變爲http://blog.codin…

  • 若咱們點擊瀏覽器的後退按鈕,頁面也不會變化,只是瀏覽器的地址欄URL變換爲以前的blog.codingplayboy.com;
  • 若咱們點擊跳轉到blog.codingplayboy.com/about.html,…
  • 咱們能夠在popstate事件回調中執行咱們的任務,可是必須知道的是,只有噹噹前頁面DOM加載完成(即DOMContentLoaded事件發生)後纔會觸發popstate事件。
  • pushState()方法不會觸發hashchange事件,即便URL的hash片斷值改變。

replaceState()

與history.pushState()方法相比,history.replaceState()方法不建立新的會話歷史,而是更新當前會話歷史記錄,如更新當前會話記錄的狀態對象或URL。

popstate事件

每次會話記錄變換激活都會在window上觸發popstate事件,若是激活的會話記錄是經過replaceState()更新的或使用pushState()方法建立的,popstate事件對象的state屬性值就是該會話記錄狀態對象的一個副本。

location.reload()與location.replace()小結

咱們知道location.reload()和location.replace()方法還有直接設置location值,均可以從新加載頁面,可是這三種方式也是有區別的:

reload()

  • 語法

    location.reload(beForceGet)

  • 參數

    beForceGet,可選,值爲truefalse;默認爲false,表示是否從客戶端緩存讀取當前頁;爲true時,則從服務端從新請求頁面(至關於F5刷新和history.go(0)方法)。複製代碼

replace()

  • 語法

    location.replace(url)

  • 參數

    一個相對或絕對URL,使用相對於當前頁URL解析後的URL替換當前會話記錄的URL,效果與使用history.replaceState()方法修改URL相同;

  • 對比reload()

    location.reload()會取客戶端的緩存頁面,可是location.replace(url)老是從新請求加載url指向的頁面。

location賦值

  • 語法

    location.href = url;

    location.assign(url);

  • 說明

    能夠爲location直接設置一個URL值,該值等效於使用pushState()修改URL,會建立一條新會話記錄。

攔截用戶返回頁面及強制請求新頁面實例

點此傳送到實例訪問地址

首先,咱們進入首頁index.html,並點擊任意跳轉,跳轉到第二頁a.html(固然在實際應用中能夠是任意頁面),而後點擊返回,咱們會發現,並無返回到咱們訪問的首頁,而是進入了咱們設置的攔截頁,具體如何實現的呢,由於咱們在第二頁中編寫JavaScript代碼實現:

;(function() {
        window.onpopstate = function(event) {
            console.log(event.state);
            location.replace('replace.html');
        };
        history.pushState({name: '驚鴻'}, '', 'a.html?history=1');
    })();複製代碼

咱們調用pushState()方法建立了一條新會話記錄(該會話URL爲a.html?history=1,仔細看瀏覽器地址欄變URL變成了a.html?history=1,),並綁定了popstate事件回調,當瀏覽器返回時,會退回到上一條會話記錄,即a.html會話,而後觸發popstate事件,在事件回調函數中,咱們調用location.replace('replace.html')將a.html頁面跳轉至replace.html(能夠是任意同源頁面),這就實現了攔截用戶跳轉;隨後,再次點擊返回,會返回到咱們訪問的第一個頁面,咱們查看NetWork請求會發現不一樣於以前返回的頁面(請求狀態碼爲304),其狀態碼是200,說明是一次新的請求,這是由於在replace.html頁面中,加了以下代碼:

;(function() {
        window.onpopstate= function(event) {
            console.log(event.state);
            document.location.replace(location.href);
        };
    })();複製代碼

咱們在popstate事件回調中,使用location.replace()方法強制刷新了當前頁面;當咱們在攔截頁點擊返回時,會回退到第一頁會話,URL爲index.html,而後觸發popstate事件,執行document.location.replace(location.href);刷新頁面。

pushState()和replaceState()能作的比咱們想象的要多,本文比較詳細的對其進行了介紹,有興趣的同窗能夠參考MDN或玩w3c,進行更深刻的學習,也能夠搜索PJAX,即PushState和Ajax,同時使用這兩個工具,能夠極大加快網站響應速度。

歡迎移步個人我的博客

相關文章
相關標籤/搜索