js--history 物件詳解

丶Serendipity丶發表於2021-11-19

 

前言

  我們瀏覽一個網頁時可能不太會注意網頁前進後退這些操作,但是在開發時你是否想過頁面之間的跳轉經歷了什麼,瀏覽器時怎麼儲存的頁面資訊,重新返回上一個頁面的時候是否需要重新載入頁面呢,會有很對疑問,要想解決這些問題,首先需要知道瀏覽器中的window下的history物件,本文來詳細總結一下該物件的相關知識點。

正文

  history 物件表示當前視窗首次使用以來使用者的導航歷史記錄。因為 history 是 window 的屬性,所以每個 window 都有自己的 history 物件。出於安全考慮,這個物件不會暴露使用者訪問過的 URL,但可以通過它在不知道實際 URL 的情況下前進和後退。

  1、路由導航

  history.go() 方法可以在使用者歷史記錄中沿任何方向導航,可以前進也可以後退。這個方法只接收一個引數,這個引數可以是一個整數,表示前進或後退多少步。

        history.go(-1);// 後退一頁
        history.go(1);// 前進一頁
        history.go(2);// 前進兩頁
        // go() 有兩個簡寫方法: back() 和 forward() 。
        history.back();// 後退一頁
        history.forward();// 前進一頁

  history 物件還有一個 length 屬性,history.length == 1表示這是使用者視窗中的第一個頁面

  histroy的go方法,back方法、forword方法以及使用者在瀏覽器手動的前進後退按鈕都會導致頁面重新整理後跳轉。

  2、歷史狀態管理API

  (1)hashchange 事件

  hashchange:history 物件的一個新特性是hashchange,會在頁面 URL 的雜湊變化時被觸發,開發者可以在此時執行某些操作。當URL的片段識別符號更改時,將觸發hashchange事件 (跟在#符號後面的URL部分,包括#符號)。而狀態管理API 則可以讓開發者改變瀏覽器 URL 而不會載入新頁面。比如:pushState和replaceState方法,頁面並不會重新整理,但是路由會發生改變。

  (2)popstate 事件

  當活動歷史記錄條目更改時,將觸發popstate事件。如果被啟用的歷史記錄條目是通過對history.pushState()的呼叫建立的,或者受到對history.replaceState()的呼叫的影響,popstate事件的state屬性包含歷史條目的狀態物件的副本。需要注意的是呼叫history.pushState()或history.replaceState()不會觸發popstate事件。只有在做出瀏覽器動作時,才會觸發該事件,如使用者點選瀏覽器的回退按鈕(或者在Javascript程式碼中呼叫history.back()或者history.forward()方法)

  (3)history.pushState() 方法

  pushState() 方法向當前瀏覽器會話的歷史堆疊中新增一個狀態(state)。這個方法接收 3 個引數:一個 state 物件、一個新狀態的標題和一個(可選的)相對 URL。pushState() 方法執行後,狀態資訊就會被推到歷史記錄中,瀏覽器位址列也會改變以反映新的相對 URL。URL欄顯示新地址, 但是不會載入 頁面,甚至不會檢查頁面是否存在,該方法會增加history.length

  (4)history.replaceState()方法

  replaceState()方法修改當前歷史記錄實體。這個方法接收 3 個引數:一個 state 物件、一個新狀態的標題和一個(可選的)相對 URL。replaceState() 方法執行後,將會更新當前的state物件或者當前歷史實體的URL來響應使用者的的動作,URL欄顯示新地址, 但是不會載入 頁面,甚至不會檢查頁面是否存在。該方法不會增加history.length。

<body>
  <button onclick="handleNext()">點我到下一頁</button><br>
  <button onclick="handleLast()">點我到上一頁</button><br>
  <script>
    window.onload = function () {
      console.log(window.history);
    }
    window.addEventListener('hashchange', function () {
      console.log('The hash has changed!')
    }, false);
    window.addEventListener('popstate', (event) => {
      console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
    });
    function handleNext() {
      const state = { userId: "1234", page: "2" }
      const title = ''
      const url = 'page2.html'
      window.history.pushState(state, title, url)
      console.log(window.history);
    }
    function handleLast() {
      const state = { userId: "1234", page: "21" }
      const title = ''
      const url = 'page21.html'
      window.history.replaceState(state, title, url)
      console.log(window.history);
    }
  </script>
</body>

執行結果如下:

  3、補充:URL的hash

  URL的hash也就是錨點(#), 本質上是改變window.location的href屬性,我們可以通過直接賦值location.hash來改變href, 但是頁面不發生重新整理,如下圖所示:

 

寫在最後

   以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。

相關文章