天天看點

利用History來實作前端路由

之前寫過利用Hash來實作前端路由的文章,這一篇是關于如何使用H5的history來實作一個前端路由

  1. Hash實作和History實作比較
  • hash
    • 實作方式

      是通過錨點來改變浏覽器的URL,展現在URL後面會加上#,并且可以通過window.onhashChange來監聽這一變化,進而我們可以建立好hash值和對應回調函數的映射關系,然後可以通過點選a标簽,實作在不重新整理頁面情況下,通過ajax發送請求擷取異步資料來改變頁面的結構。

    • 優點

      實作方式較為簡單,有現成的hashChange來監聽路由哈希變化,相容性較好,大部分浏覽器支援

    • 缺點

      ’#‘ 不太美觀;由于Hash對于服務端來說是不可見的,是以對于SEO不友好;浏覽器的前進後退功能受到限制

  • History
    • 實作方式

      是通過history.pushState或者history.replaceState這樣的API錨點來改變浏覽器的曆史記錄堆棧,這個行為并不會引起頁面的重新整理,但是頁面的URL會改變,但是和上一種方法相比,并沒有友善的hashChange來監聽這一變化。但是可以從3個角度來入手去控制。稍後做詳細說明

    • 優點

      位址欄不會有#出現,可以利用浏覽器的前進後退功能

    • 缺點

      實作需要考慮多種路由變化的情況;相容性相對較差

  1. 利用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去異步擷取資料渲染頁面結構

繼續閱讀