前端路由的原理和實現

論前端搬磚工的自我修養發表於2019-04-28

現在基本都是單頁面應用,現在單頁面應用能夠模擬多頁面應用的效果,歸功於其前端路由機制。現在前端路由有兩種形式:

Hash模式

如: xxx.xx.com/#/hash, 這種方式可以實現重新整理跳轉,不需要後端進行配合,主要是得益於haschange事件,當錨點雜湊改變時,就會呼叫haschange函式,

haschange模擬實現

(function(window) {
  // 如果瀏覽器原生支援該事件,則退出  
 if ( "onhashchange" in window.document.body ) { return; }
 var location = window.location,
 oldURL = location.href,
 oldHash = location.hash;
 // 每隔100ms檢測一下location.hash是否發生變化
 setInterval(function() {
    var newURL = location.href,
    newHash = location.hash;
    // 如果hash發生了變化,且繫結了處理函式...
    if ( newHash != oldHash && typeof window.onhashchange === "function" ) {
    // execute the handler
      window.onhashchange({
        type: "hashchange",
        oldURL: oldURL,
        newURL: newURL
      });

      oldURL = newURL;
      oldHash = newHash;
    }
  }, 100);
})(window);
複製程式碼

例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <ul>
       <li><a href="#/css">css</a></li>
       <li><a href="#/js">js</a></li>
       <li><a href="#/node">node</a></li>
   </ul>
   <div class="wrapper">
       當前選擇的是:<span></span>
   </div>
</body>
<script>
    window.onhashchange = function (e) {
        console.log(e);
        document.querySelector('.wrapper span').innerText = location.hash.split('/')[1]
    }
</script>
</html>
複製程式碼

前端路由的原理和實現

前端路由的原理和實現

H5模式

如:xxx.xx.com/hash 這種模式需要後端路由配合使用。HTML5的History API為瀏覽器的全域性history物件增加的擴充套件方法。一般用來解決ajax請求無法通過回退按鈕回到請求前狀態的問題

在HTML4中,已經支援window.history物件來控制頁面歷史記錄跳轉,常用的方法包括:

  • history.forward(); //在歷史記錄中前進一步
  • history.back(); //在歷史記錄中後退一步
  • history.go(n): //在歷史記錄中跳轉n步驟,n=0為重新整理本頁,n=-1為後退一頁。

在HTML5中,window.history物件得到了擴充套件,新增的API包括:

  • history.pushState(data[,title][,url]);//向歷史記錄中追加一條記錄
  • history.replaceState(data[,title][,url]);//替換當前頁在歷史記錄中的資訊。
  • history.state;//是一個屬性,可以得到當前頁的state資訊。
  • window.onpopstate;//是一個事件,在點選瀏覽器後退按鈕或js呼叫forward()、back()、go()時觸發。監聽函式中可傳入一個event物件,event.state即為通過pushState()或replaceState()方法傳入的data引數。注意呼叫pushState和replaceState不會觸發onpopstate事件
   history.pushState({page: 1}, null, '?page=1');
    history.pushState({page: 2}, null, '?page=2');

    history.back(); //瀏覽器後退

    window.addEventListener('popstate', function(e) {
        //在popstate事件觸發後,事件物件event儲存了當前瀏覽器歷史記錄的狀態.
        //e.state儲存了pushState新增的state的引用
        console.log(e.state);  //輸出 {page: 1}
    });
複製程式碼

前端路由的原理和實現

相關文章