history.pushState()
EC前端 - history.pushState()
描述
history.pushState()
方法可以無重新整理地向目前history插入一條曆史狀态。
什麼是曆史狀态(history state)?
曆史狀态就是你在浏覽器的目前Tab頁中加載的頁面,這些頁面以時間作為先後順序排列,稱為曆史狀态清單。
曆史狀态分為兩種:
- 由傳統的網頁加載生成的曆史狀态,即向伺服器請求新的頁面.
- 通過
方法生成的曆史狀态,并不會向伺服器請求新頁面。pushState()
有了曆史狀态,浏覽器的前進後退按鈕就處于可用狀态,可以在曆史狀态之間來回跳轉。
注意:重新整理不會産生曆史狀态。
文法
history.pushState(stateObject, title, url);
參數
參數 | 描述 |
---|---|
| 傳入的狀态對象。目前進(後退)到某一新的狀态時,會觸發 事件。此事件對象event.state存儲的就是這個 的值。 |
| 新狀态的标題。(目前,大多數浏覽器并不支援該參數,建議傳 值) |
| 狀态對應的曆史記錄的位址。 |
pushState有什麼用?
或者說,為什麼需要無重新整理地插入一條曆史狀态。
随着Ajax技術的普及,尤其是單頁面應用的流行。網頁對資料的加載更多的是通過無重新整理的異步加載來完成。這樣确實大大提升了使用者體驗,但也造成了一個困擾。
要知道,Ajax加載資料并不會生成曆史狀态,前進後退按鈕也就無法激活,那現在我要後退到上一次展示資料的狀态,該怎麼回去呢?
答案很明顯,就是在完成一次Ajax請求的同時,為浏覽器創造一個曆史狀态。
history.pushState()
要做的就是這件事!
pushState的應用場景案例:
現在有一個報表應用用于展示某年的銷售資料:
剛打開時,沒有任何報表資料:
2015 2016 2017 2018
一季度 | 二季度 | 三季度 | 四季度 | 總和 |
---|---|---|---|---|
無 | 無 | 無 | 無 | 無 |
假定此時的URL:
http://example.com/getFinaData.php
點選按鈕通過Ajax加載2015年的資料
2015 2016 2017 2018
一季度 | 二季度 | 三季度 | 四季度 | 總和 |
---|---|---|---|---|
122萬 | 147萬 | 135萬 | 153萬 | 557萬 |
同時我們為這一次資料加載新增一條曆史狀态:
此時的URL變為:
http://example.com/getFinaData.php?year=2015
同時你會發現浏覽器的後退按鈕激活了,而網頁并沒有請求伺服器。因為在
pushState()
的作用下無重新整理地新增了一條曆史狀态。
點選按鈕通過Ajax方式加載2018年的資料
2015 2016 2017 2018
四月份 | 五月份 | 六月份 | 總和 |
---|---|---|---|
15萬 | 10萬 | 11萬 | 36萬 |
重複上一步,我們再為這一次資料加載新增一條曆史狀态:
此時的URL變為:
http://example.com/getFinaData.php?year=2018
現在,我們使用後退鍵,看看會發生什麼?
URL重新變回:
http://example.com/getFinaData.php?year=2015
但是,界面并沒有發生變化(表格依舊顯示的是2018年的資料)。
因為點選後退鍵隻是簡單地切回到上一個狀态,而這個狀态是無重新整理的,我們要做的捕獲這個切換到的狀态,并擷取上一次儲存的狀态值(
pushState()
的第一個參數),然後再調用一次ajax請求資料
浏覽器提供了
popState
事件用于捕獲前進後退時切換到的狀态。上一次儲存的狀态值(
pushState()
的第一個參數)儲存在事件對象event.state中。
window.onpopstate = function(event) {
// 擷取存儲的狀态
var params = event.state; // {year: 2015}
// 根據存儲的狀态,再次使用Ajax加載資料并插入到視圖中
// ...具體代碼省略
};
現在,成功實作無重新整理後退到上一次界面:
2015 2016 2017 2018
一季度 | 二季度 | 三季度 | 四季度 | 總和 |
---|---|---|---|---|
122萬 | 147萬 | 135萬 | 153萬 | 557萬 |