hash 和 history是主流的兩種前端路由實現(xiàn)方式
History API
關(guān)于history的詳細用法 請點擊這里
主要說一下新增的兩個API history.pushState()
和 history.replaceState()
history
pushState()
和 history.replaceState()
一樣采用三個參數(shù):狀態(tài)對象沙庐,標題(當前被忽略)和(可選)URL亿扁。讓我們更詳細地研究這三個參數(shù)中的每一個
-
狀態(tài)對象(state object) — 一個JavaScript對象掖桦,與用
pushState()
方法創(chuàng)建的新歷史記錄條目關(guān)聯(lián)。無論何時用戶導航到新創(chuàng)建的狀態(tài)畔柔,popstate
事件都會被觸發(fā),并且事件對象的state
屬性都包含歷史記錄條目的狀態(tài)對象的拷貝课锌。 - 標題(title) — FireFox瀏覽器目前會忽略該參數(shù)乔宿,雖然以后可能會用上∥ǖ考慮到未來可能會對該方法進行修改九秀,傳一個空字符串會比較安全≌澄遥或者鼓蜒,你也可以傳入一個簡短的標題,標明將要進入的狀態(tài)征字。
-
地址(URL) — 新的歷史記錄條目的地址都弹。瀏覽器不會在調(diào)用
pushState()
方法后加載該地址,但之后匙姜,可能會試圖加載畅厢,例如用戶重啟瀏覽器。新的URL不一定是絕對路徑氮昧;如果是相對路徑框杜,它將以當前URL為基準;傳入的URL與當前URL應該是同源的袖肥,否則咪辱,pushState()
會拋出異常。該參數(shù)是可選的昭伸;不指定的話則為文檔當前URL梧乘。
history.replaceState()
操作完全一樣history.pushState()
,只是replaceState()
修改當前的歷史條目庐杨,而不是創(chuàng)建一個新的选调。請注意,這不會阻止在全局瀏覽器歷史記錄中創(chuàng)建新條目灵份。
replaceState()
當您想要更新當前歷史記錄條目的狀態(tài)對象或URL以響應某些用戶操作時仁堪,此功能特別有用。
不同之處在于填渠,pushState()
會增加一條新的歷史記錄弦聂,而replaceState()
則會替換當前的歷史記錄。
舉一個例子
在百度頁面打開控制臺輸入
window.history.pushState(null, null, "https://www.baidu.com/?name=history");
按下回車會發(fā)現(xiàn)地址欄變成這樣
上面的例子中 改變url頁面并沒有刷新氛什,同樣根據(jù)API所述莺葫,瀏覽器會產(chǎn)生瀏覽記錄
注意pushState()
的url不支持跨域
通過用戶的歷史記錄中向后和向前移動使用做了back(),forward()和go() 方法枪眉。
這里就不多做介紹了 詳情點擊這里
hash
我們經(jīng)常在 url 中看到 #捺檬,這個 # 有兩種情況,一個是我們所謂的錨點贸铜,比如典型的回到頂部按鈕原理堡纬、Github 上各個標題之間的跳轉(zhuǎn)等聂受,路由里的 # 不叫錨點,我們稱之為 hash烤镐,大型框架的路由系統(tǒng)大多都是哈希實現(xiàn)的蛋济。
同樣我們需要一個根據(jù)監(jiān)聽哈希變化觸發(fā)的事件 ——hashchange
事件
我們用 window.location
處理哈希的改變時不會重新渲染頁面,而是當作新頁面加到歷史記錄中炮叶,這樣我們跳轉(zhuǎn)頁面就可以在 hashchange
事件中注冊 ajax 從而改變頁面內(nèi)容碗旅。
hashchange
在低版本 IE 需要通過輪詢監(jiān)聽 url 變化來實現(xiàn),我們可以模擬如下
(function(window) {
// 如果瀏覽器不支持原生實現(xiàn)的事件悴灵,則開始模擬扛芽,否則退出。
if ( "onhashchange" in window.document.body ) { return; }
var location = window.location,
oldURL = location.href,
oldHash = location.hash;
// 每隔100ms檢查hash是否發(fā)生變化
setInterval(function() {
var newURL = location.href,
newHash = location.hash;
// hash發(fā)生變化且全局注冊有onhashchange方法(這個名字是為了和模擬的事件名保持統(tǒng)一)
if ( newHash != oldHash && typeof window.onhashchange === "function" ) {
// 執(zhí)行方法
window.onhashchange({
type: "hashchange",
oldURL: oldURL,
newURL: newURL
});
oldURL = newURL;
oldHash = newHash;
}
}, 100);
})(window)
個人感覺還是hash方案好一點积瞒,因為照顧到低級瀏覽器川尖,就是多了#號感覺不太美觀,兩者兼容也是可以的茫孔,只能根據(jù)瀏覽器的版本給出對應的方案 不過也支持IE8+ 還是不錯的