1. 程式人生 > >實現不重新整理整個頁面進行前進後退

實現不重新整理整個頁面進行前進後退

在html5出來前,實現無重新整理前進後退通常是結合location.hash+onhashchange事件來實現的;
在html5出來後,可以使用h5 history api來實現無重新整理前進後退

點選瀏覽器的前進後退按鈕時,只要將要進入的頁面與當前頁面不是同一個頁面(因為有可能人為地添加了一條歷史記錄,但實際上還是同一個頁面),那麼將要進入的頁面其所有請求(包括html、js、css、json和圖片等)都是直接從快取裡讀取的(除非禁用了快取),但js還是會重新執行一遍。如果該頁面是用ajax獲取資料的,那麼不管前進或者後退到該頁面時,都會重新ajax請求資料。


HTML5中history那些事

SEPTEMBER 26TH, 2015
HTML5中History物件提供了兩個新的方法,pushState和replaceState用來在無重新整理頁面情況下更改url,為單頁應用提供了很大方便,但是在使用時需要注意一些事情。

原來有什麼
History物件原來有三個方法,一個屬性。

history.length:歷史列表中的網址數。
history.back():載入歷史列表前一個網址。
history.forward():載入歷史列表後一個網址。
history.go(num):載入歷史列表中的某個頁面,引數為相對當前頁面,跳轉的次數。go(-1)與back()效果相同,go(1)與forward()效果相同。go(-2)與單擊兩次後退按鈕執行的操作一樣。

新增了什麼
History物件新增了兩個方法,一個屬性,新增了一個事件。

history.pushState(state,title,url):替換url為當前url並新增歷史記錄,title為歷史記錄的title,state為一個使用者儲存的物件,可以通過history.state或window.onpopstate事件的event.state訪問。
history.replaceState(state,title,url):引數與history.pushState相同,不同點在於該方法更改當前歷史記錄,不會產生新的歷史記錄。
history.state:使用者儲存的物件。
window.onpopstate:當使用history.pushState或history.replaceState控制歷史記錄後,觸發瀏覽器的前進/回退操作會觸發該事件。

注意事項
state屬性不能通過history.state或window.onpopstate的event.state來修改,只能通過history.pushState或history.replaceState修改。
state屬性必須是可序列化的值,如DOM物件不可設定。
history.state與window.onpopstate的event.state不相等。
history.pushState與history.replaceState的url引數與網站url必須是同域的,否則會出現跨域錯誤。需要注意,當history.pushState或history.replaceState的url引數為/abc/def或abc/def時所使用的origin為載入該<script>的origin,如果操作History的是外部js檔案,請拼接上location.origin。

還差什麼
當前在哪
History沒有提供獲取當前頁面在歷史列表位置的方法,這個屬性作用不大,只有在單頁應用,且擁有非順序跳轉邏輯時才會用到,既然系統不提供,只能自己推算。
首先要保證每個頁面設定state屬性,這樣可以通過該屬性判斷是否是已經載入過頁面。 當首次載入應用時,檢查history.state屬性,如果該屬性未設定,那麼必然為新開頁面,此時必然為歷史列表第一個,當使用history.pushState後,邏輯同上。,此兩種情況current為history.length。其餘情況即為頁面跳轉或當前頁面重新整理,current即為之之前兩種情況儲存的值。


HTML4中的History API
屬性
length 歷史的項數。javascript 所能管到的歷史被限制在用瀏覽器的“前進”“後退”鍵可以去到的範圍。本屬性返回的是“前進”和“後退”兩個按鍵之下包含的地址數的和。
方法
back() 後退,跟按下“後退”鍵是等效的。
forward() 前進,跟按下“前進”鍵是等效的。
go() 用法:history.go(x);在歷史的範圍內去到指定的一個地址。如果 x < 0,則後退 x 個地址,如果 x > 0,則前進 x 個地址,如果 x == 0,則重新整理現在開啟的網頁。history.go(0) 跟 location.reload() 是等效的。

HTML5中的History API(使用h5的history api可以不用更改頁面url的hash值)

操縱瀏覽器的歷史記錄
  1. history.pushState(data, title [, url]):往歷史記錄堆疊頂部新增一條記錄;data會在onpopstate事件觸發時作為引數傳遞過去;title為頁面標題,當前所有瀏覽器都會 忽略此引數;url為頁面地址,可選,預設為當前頁地址。
  2. history.replaceState(data, title [, url]) :更改當前的歷史記錄,引數同上。
  3. history.state:獲取歷史棧中最頂端的state資料(即history.pushState中的第一個引數),不同瀏覽器的讀寫許可權不一樣。
  4. popstate事件:當用戶單擊瀏覽器的後退或者前進按鈕(或者呼叫history.go,history.back,history.forward方法也會觸發popstate事件。呼叫history.pushState()或者history.replaceState()不會觸發popstate事件,但改變url中的hash值會觸發popstate事件)時觸發該事件。在事件處理函式中讀取觸發事件的事件物件的state屬性值,該屬性值即為執行pushState方法時所使用的第一個引數值,該state與history.state是相同的,而不是歷史棧中被丟擲的state物件。
到目前為止,IE10,firefox4以上的版本,Chrome8以上的版本,Safari5,Opera11以上的版本瀏覽器支援HTML5中的History API。

判斷是否支援h5 history api:
if ('pushState' in history) { ... };

h5 history api實現無重新整理跳轉

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <!DOCTYPE html> <html lang="en"> <!-- saved from url=(0014)about:internet --> <head> <meta charset="UTF-8"> <title></title> </head> <body> <a h