查了很多資料,似乎都是用ajax局部刷新到另一個頁面,即有兩個html文件,使用window.onpopstate和history.pushState方法保存歷史記錄及回退頁面。想請問下如果用ajax還是在目前頁面產生資料該怎麼實現瀏覽器的後退功能?能給個具體的例子嗎?
PHP中文网2017-05-19 10:34:59
ajax的一大痛點就是無法支援瀏覽器前進和後退操作. 因此早期的Gmail 採用 iframe, 來模擬ajax的前進和後退.
如今, H5普及, pjax大行其道. pajax 就是 ajax+history.pushState 組合的一種技術. 使用它便可以無刷新通過瀏覽器前進和後退來改變頁面內容.
先看下相容性.
IE | Edge | Firefox | Chrome | Safari | Opera | iOS Safari | Android Browser | Chrome for Android | |
---|---|---|---|---|---|---|---|---|---|
pushState/replaceState | 10 | 12 | 4 | 5 | 6 | 11.5 | 7.1 | 4.3 | 53 |
history.state | 10 | 4 | 18 | 6 | 11.5 |
可見IE8,9並不能使用 H5的history. 需要使用墊片 HTML5 History API expansion for browsers not supporting pushState, replaceState .
pjax簡單易用, 只需要如下三個api:
history.pushState(obj, title, url) 表示往頁面history末尾新增一個歷史項目(history entry), 此時history.length會+1.
history.replaceState(obj, title, url) 表示替換當前歷史項為新的歷史項. 此時history.length保持不變.
window.onpopstate 僅在瀏覽器前進和後退時觸發(history.go(1), history.back() 及location.href="xxx" 均會觸發), 此時可在history.state中拿到剛塞進去的state, 即obj物件(其他資料型態亦可).
我們注意到, 首次進入一個頁, 此時 history.length
值为1, history.state
為空. 如下:
1) 為了在onpopstate事件回呼中每次都能拿到 history.state
, 此時需要在頁面載入完成後, 自動替換下當前url.
history.replaceState("init", title, "xxx.html?state=0");
2) 每次發送ajax請求時, 在請求完成後, 呼叫如下, 從而實現瀏覽器history往前進.
history.pushState("ajax请求相关参数", title, "xxx.html?state=标识符");
3) 瀏覽器前進與後退時, popstate
事件會自動觸發, 此時我們手動取出popstate
事件会自动触发, 此时我们手动取出 history.state
, 建置參數並重新傳送ajax請求或直接取用state值, 從而實現無刷新還原頁面.
window.addEventListener("popstate", function(e) {
var currentState = history.state;
//TODO 拼接ajax请求参数并重新发送ajax请求, 从而回到历史页面
//TODO 或者从state中拿到关键值直接还原历史页面
});
popstate
事件触发时, 默认会传入 PopStateEvent
事件物件. 該物件具有以下屬性.
如有不懂, 更詳細講解請移步 : ajax與history的兼容