操作瀏覽歷史

This translation is incomplete. Please help translate this article from English.

DOM window 物件透過 history 物件,提供了進入瀏覽歷史的方式。他透過一些方便的屬性與方法,讓你可以在歷史紀錄中往前或往後移動,並且讓你—從 HTML5 開始—能操作歷史紀錄的內容。

在歷史紀錄中移動

往前往後歷史紀錄可以用 back(), forward(), 和 go() 的方法。

往前往後

要在歷史紀錄中往後移動,可以:

window.history.back();

這完全等同於用戶在瀏覽器上點選「上一頁」按鈕。

同樣的,你也可以往前移動(等同於用戶點擊往前的按鈕)

window.history.forward();

移動到特定的歷史紀錄

你可以用 go() 方法來從頁面的 session 歷史記錄中載入特定紀錄, 以目前頁面的相對位置而定(目前的頁面想當然爾是 index 0)。

往前一頁(等同於呼叫 back()):

window.history.go(-1);

往後一頁(等同於呼叫 forward()):

window.history.go(1);

同樣的你也可以傳入 2 這個直往前兩頁,依此類推。

你可以查看 length 這個屬性來取得目前瀏覽歷史的總數 :

var numberOfEntries = window.history.length;
注意: Internet Explorer 支援在 go() 中以 URL 的值作為參數;這不在標準中,Gecko 也不支援。

加入和修改歷史紀錄

HTML5 加入了 history.pushState()history.replaceState() 方法,讓你可以加入或修改歷史紀錄。這些方法都可以跟 window.onpopstate 事件一同應用。

使用 history.pushState()後,會改變 XMLHttpRequest 時 HTTP 標頭中 referrer 的值。referrer 會是創造 XMLHttpRequest 物件時的當前視窗文件(this)的 URL。

範例

假設 http://mozilla.org/foo.html 執行了下面的 JavaScript:

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

這會讓網址列顯示 http://mozilla.org/bar.html,但不會讓瀏覽器去載入 bar.html,甚或去檢查 bar.html 存在與否。

假設現在使用者瀏覽到 http://google.com,然後點擊上一頁鈕。這時網址列會顯示 http://mozilla.org/bar.html,頁面會獲得 popstate 的事件(state object 會包含一份 stateObj 的副件)。頁面長得跟 foo.html 一樣,雖然可能在 popstate 事件執行中被修改。

如果我再點一次上一頁鈕, 網址會改變成為 http://mozilla.org/foo.html,且文件會得到另外一個 popstate 事件,此次會包含一個空的(null)state object。同樣的,回上頁鈕不會改變文件的內容,只是文件可能會在 popstate 事件中被手動更新。

pushState() 方法

pushState() 取用三個參數:一個 state 物件、title(目前會省略)與 URL(可選用)。我們來看看三個參數的細節之處:

  • state object — state object 是一個 JavaScript 的物件可以讓你創造一個 pushState() 的新的歷史入口。只要使用者到了新的 state ,一個 popstate 的事件就會被觸發,然後 state 屬性會包含一個複製的歷史入口狀態。

state 物件可以是任何串連話的東西。因為 Firefox 儲存 state 物件到使用者的硬碟所以他們可以恢復當瀏覽器被重新啟動的時候。我們限制了只可以有 640k 個字元的 state object。如果你傳送了比這個更大的 pushState() ,這個方法會丟出一個例外事件。如果你需要更多空間的話,你可以試著用 sessionStorage 和/或 localStorage

  • title — Firefox 目前省略了這個參數,雖然他以後有可能會被使用。如果以後改變了這個方法,傳送一個空白的字元應該還是會安全的。另外,你可以傳送一個短的標題來敘述你想要到的 state

  • URL — 一個新的歷史入口的 URL 從這個參數做設定。值得注意的是瀏覽器並不會去 load 這個 URL 在 pushState() 被呼叫的時候,但是他會 load URL 在後面的時候,例如使用者重新開啟他的瀏覽器。新的 URL 不一定需要為一個絕對的路徑。新的 URL 需要與目前 URL 的 origin 是一樣的; 否則,pushState() 會丟出一個錯誤的例外。這個參數是選擇性的; 如果沒有被指定的話,他會設定為目前文件的 URL。

注意: 在 Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) 到 Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), 傳送這個物件利用 JSON。從 Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3) 開始, 這個物件序列化利用 the structured clone algorithm。這會可以有更多有更多不同的物件可以被安全的傳送。

從某種意義上,呼叫 pushState() 是同樣的設定 window.location = "#foo",兩個都會去創造和繳活另一個歷史紀錄在目前的文件中。但是 pushState() 有一些優勢的地方:

  • 一個新的 URL 可以被任何 URL 在同一個 origin 中當做是目前的 URL,相對來說,設定 window.location 可以讓你在同一個 document 唯一不同的就是加了一個 hash 
  • 你可以不必去改變 URL 如果你不想要的話。相對來說,設定 window.location = "#foo"; 只有創造一個新的歷史紀錄如果目前的 hash 不是 #foo 的話。
  • 你可以用相關的 arbitrary data 在你的新的歷史紀錄。用 hash-based 的方法你需要編碼一個相對短的自串。

注意 pushState 永遠不會造成一個 hashchange 的事件被觸發,雖然新的 URL 和舊的 URL 只有在 hash 的部份不一樣而已。

replaceState() 方法

history.replaceState() 的執行就像 history.pushState() 但是除了 replaceState() 更動了目前的歷史紀錄並創造了一個新的。

replaceState() 很實用的原因是當你要更新一個 state 的物件或是 URL 從目前的歷史紀錄來回復一些使用者的動作。

注意: 在 Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) 到 Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), 傳送這個物件利用 JSON。從 Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3) 開始, 這個物件序列化利用 the structured clone algorithm。這會可以有更多有更多不同的物件可以被安全的傳送。

popstate 事件

一個 popstate 事件會被派遣每次 active 的歷史紀錄被更動的話。如果歷史紀錄被繳活可以呼叫 pushState 或是呼叫 replaceStatepopstate 事件的 state 包含了一個副本給歷史紀錄的 state 物件。

可以看 window.onpopstate 裡面有些範例。

閱讀目前的 state

當你讀取頁面的時候,可能會有 non-null state 的物件。這可以被發生,例如說,如果你設定一個 state 物件(用 pushState() 或是 replaceState()),然後使用者可以重新啟動他的瀏覽器。當你的頁面重洗的時候,頁面會得到一個 onload 的事件,但是沒有 popstate 事件。然而,如果你閱讀了 history.state 屬性,你會得到一個 state 物件如果 popstate 被啟動的話。

你可以得到一個目前的歷史紀錄,你並不需要等待 popstate 可以直接用 history.state 屬性:

var currentState = history.state;

範例

這個完整的範例請到 AJAX 網站,請看:Ajax navigation example.

瀏覽器支援度

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
replaceState, pushState 5 4.0 (2.0) 10 11.50 5.0
history.state 18 4.0 (2.0) 10 11.50 6.0
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
replaceState, pushState ? ? ? ? ?
history.state ? ? ? ? ?

相關

Document Tags and Contributors

標籤: 
Contributors to this page: irvinfly, Klern, Sheppy, ChiLiJung
最近更新: irvinfly,