發現一個可以改變地址欄,而不導致頁面刷新的東東。 Chrome, FF測試通過,不支持IE.
實現目標
- 頁面的跳轉(前進后退,點擊等)不重新請求頁面
- 頁面URL與頁面展現內容一致(符合人們對傳統網頁的認識)
- 在不支持的瀏覽器下降級成傳統網頁的方式
使用到的API
history.state
當前URL下對應的狀態信息。如果當前URL不是通過pushState或者replaceState產生的,那么history.state是null。
history.pushState(state, title, url)
將當前URL和history.state加入到history中,並用新的state和URL替換當前。不會造成頁面刷新。
state:與要跳轉到的URL對應的狀態信息。
title:不知道干啥用,傳空字符串就行了。
url:要跳轉到的URL地址,不能跨域。
history.replaceState
用新的state和URL替換當前。不會造成頁面刷新。
state:與要跳轉到的URL對應的狀態信息。
title:不知道干啥用,傳空字符串就行了。
url:要跳轉到的URL地址,不能跨域。
window.onpopstate
history.go和history.back(包括用戶按瀏覽器歷史前進后退按鈕)觸發,並且頁面無刷的時候(由於使用pushState修改了history)會觸發popstate事件,事件發生時瀏覽器會從history中取出URL和對應的state對象替換當前的URL和history.state。通過event.state也可以獲取history.state。
支持性判斷
if ('pushState' in history) {...}
實現思路
用戶通過“點擊觸發”,“操作歷史”,“直接訪問URL”的方式修改當前URL。這三種觸發方式會使瀏覽器做出不同的行為。如果頁面做無刷跳轉,那么頁面具體顯示什么內容需要js來控制,js則需要根據一些信息來知道當前應該顯示什么內容,這個信息就是history.state。這樣我們只要保持URL和history.state一一對應,就能保證URL和內容一一對應。大部分情況下URL和history.state都是一一對應的,但通過直接URL訪問頁面的方式進入頁面,history.state是null,所以我們需要把URL轉換成對應的history.state寫入。我們不能直接寫入history.state,需要通過replaceState的方式寫入。對於不支持pushstate的瀏覽器,一律修改href跳轉頁面,等同於直接訪問URL。示意圖如下。