前端路由的核心原理是更新頁面但不向服務器發(fā)起請求灿意,目前在瀏覽器環(huán)境中這一功能的實現(xiàn)主要有兩種方式:
- 利用URL中的hash(“#”)
- 利用HTML5新增的方法History interface
參考:js單頁hash路由原理與應用實戰(zhàn) 里的
HTML代碼
<section>
<ul>
<li><a href="#/">全部</a></li>
<li><a href="#/html">html課程</a></li>
<li><a href="#/css">css課程</a></li>
<li><a href="#/javascript">javascript課程</a></li>
</ul>
</section>
js代碼
class Router{
constructor(){
this.routs={};
this.curURL = '';
}
//監(jiān)聽路由變化
init(){
console.log(this);
window.addEventListener("hashchange", this.reloadPage);
}
//獲取路由參數(shù)
reloadPage(){
console.log(this);
this.curURL = location.hash.substring(1) || "/";
this.routs[this.curURL]();
}
//保存路由對應的函數(shù)
map(key,callback){
this.routs[key] = callback;
}
}
const iRouter = new Router();
iRouter.map("/", ()=>{
let oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = 'html,css,javascript';
})
iRouter.map("/html",()=>{
let oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = 'html5';
})
iRouter.map("/css",()=>{
let oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = 'css';
})
iRouter.map("/javascript",()=>{
let oSidebar = document.querySelector("sidebar");
oSidebar.innerHTML = 'javascript';
})
iRouter.init();
window.addEventLister("hashchange",this.reloadPage.bind(this))
對于本渣這行代碼有幾個要學習知識點
- 當 一個窗口的哈希改變時就會觸發(fā) hashchange 事件。即URL由“index.html#/”變?yōu)椤癷ndex.html#/css”時,執(zhí)行reloadPage方法摹察。
- 為什么使用bind, MDN關于this的文檔里寫到“函數(shù)被用作DOM事件處理函數(shù)時,它的this指向觸發(fā)事件的元素”蹄梢。這里不綁定this的話稽亏,執(zhí)行時this就是window對象。
- bug解決缕题,當不綁定this時點擊導航會報錯:Uncaught TypeError: Cannot read property '/css' of undefined at reloadPage 截歉;控制臺查看js 錯誤提示停留在
this.routs[this.curURL]()
; this.reloadPage相當于window.reloadPage。window上臨時生成了一個空的reloadPage方法烟零。所以會報以上錯誤瘪松;