之前寫過利用Hash來實作前端路由的文章,這一篇是關于如何使用H5的history來實作一個前端路由
- Hash實作和History實作比較
- hash
-
實作方式
是通過錨點來改變浏覽器的URL,展現在URL後面會加上#,并且可以通過window.onhashChange來監聽這一變化,進而我們可以建立好hash值和對應回調函數的映射關系,然後可以通過點選a标簽,實作在不重新整理頁面情況下,通過ajax發送請求擷取異步資料來改變頁面的結構。
-
優點
實作方式較為簡單,有現成的hashChange來監聽路由哈希變化,相容性較好,大部分浏覽器支援
-
缺點
’#‘ 不太美觀;由于Hash對于服務端來說是不可見的,是以對于SEO不友好;浏覽器的前進後退功能受到限制
-
- History
-
實作方式
是通過history.pushState或者history.replaceState這樣的API錨點來改變浏覽器的曆史記錄堆棧,這個行為并不會引起頁面的重新整理,但是頁面的URL會改變,但是和上一種方法相比,并沒有友善的hashChange來監聽這一變化。但是可以從3個角度來入手去控制。稍後做詳細說明
-
優點
位址欄不會有#出現,可以利用浏覽器的前進後退功能
-
缺點
實作需要考慮多種路由變化的情況;相容性相對較差
-
-
利用History具體實作前端路由思路
首先路由的切換可能由這麼幾個行為引起,我們需要做不同的處理。
– 點選a連結
這種方式隻需要在他的onclick事件先阻止他的預設跳轉行為,然後擷取他的url,調用pushState/replaceState改變URL,然後根據url和回調函數的映射關系,觸發相應的動作
– 直接在腳本中調用pushState/replaceState
這種方式本質上和上述相同
– 點選浏覽器的前進/後退按鈕,這裡需要用到另一個事件,onpopState,當激活浏覽器曆史記錄時會被觸發,注意這個事件不會被pushState/replaceState觸發,這個事件回調會可以擷取到目前路由下,我們之前通過pushState/replaceState存入的資訊,也可以拿到url資訊,然後根據映射關系去執行回調。大緻代碼如下,提供個思路
var routeMap = {
route1:callback1,
route2:callback2,
route3:callback3
};
// 監聽popState事件
window.onpopstate = function(event){
var state = event.state;
routeMap[state.route].call(this);
}
a連結如下
<a href="route1" target="_blank" rel="external nofollow" onClick='clickHandler'> click </a>
對應的click方法大緻如下
function clickHandler (event){
var route = event.target.href;
history.pushState({route:route},null,route);
routeMap[route].call(this);
return false;
}
這樣一來,就實作了URL的變化,而視圖的變化實際上就是callback裡面的操作了,一般情況就是通過ajax去異步擷取資料渲染頁面結構