之前的路由都是由後端實現的,根據url來從新載入頁面。可是近年來前端頁面變得愈來愈複雜致使服務器端壓力愈來愈大。天然出現瞭解決方案,經過url的改變,在不刷新頁面的狀況下,修改頁面內容,這就是本文將要介紹的前端路由。html
前端路由的兩種實現方式:前端
何爲hashnode
直接進入栗子,經過代碼來說解hash路由原理。
咱們要實現的效果就是點擊左側導航按鈕,切換至對應的路由,而且改變內容區域顯示。
也能夠手動改變路由地址,而後內容區域也隨之變化。
如圖所示:
100行左右的代碼就能夠實現這樣簡單的效果。後端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>route demo</title> <style> * {padding: 0;margin: 0;} ul li {list-style: none;text-align: center;} .main {display: flex;height: 600px;} .main .sidebar {width: 200px;border: 2px solid red;} .main .sidebar ul {padding-top: 100px;} .main .sidebar ul li {margin-bottom: 20px;cursor: pointer; } .main .content {flex: 1;border: 2px solid green;padding: 20px;} </style> </head> <body> <div class="main"> <div class="sidebar"> <ul class="sidebar-ul"> <li class="stuManage">學生管理</li> <li class="lesManage">課程管理</li> <li class="claManage">班級管理</li> </ul> </div> <div class="content"></div> </div> <script> // 定義Route,路由對象構造函數 function Route(option) { this.routes = option.routes; this.init(); } // 爲Route添加原型方法 Route.prototype = { constructor: Route, // 初始化 init() { // 監聽window對象的hashchange事件來獲取路由的變化 window.addEventListener("hashchange", (function (e) { // e.oldURL e.newURL // 獲取改變後的hash值 var hash = location.hash.substring(1); // 將hash跟本地保存的的路由中的path進行匹配,匹配到指定路由,就執行指定模塊的代碼 // 若是找不到符合條件的元素,那麼route值爲空 var route = this.routes.find(item => { return item.path === hash; }); if (route) { route.component(hash); } }).bind(this)); // 註冊好事件後,當即觸發事件,在瀏覽器刷新後不會觸發window的hashchange事件,因此須要手動觸發 var changeEvent = new Event('hashchange'); window.dispatchEvent(changeEvent); }, // 路由跳轉 push({path}) { if (path) { location.hash = "#" + path; } } } // 根據路由的改變切換頁面顯示內容 function changePage(page) { var contentDom = document.querySelector('.main .content'); if (page === '/' || page === '/student') { contentDom.innerHTML = 'student module'; } else if (page === '/lesson') { contentDom.innerHTML = 'lesson module'; } else if (page === '/class') { contentDom.innerHTML = 'class module'; } } window.onload = function () { // 調用構造函數,實例化路由對象,初始化路由配置 var router = new Route({ routes: [ { path: "/", component: changePage }, { path: "/student", component: changePage }, { path: "/lesson", component: changePage }, { path: "/class", component: changePage } ] }); // 爲導航註冊點擊事件切換路由 document.querySelector('.sidebar-ul').addEventListener("click", function (e) { if (e.target.nodeName == "LI") { var domClassName = e.target.className; if (domClassName.indexOf('stuManage') > -1) { router.push({ path: "/student" }) } else if (domClassName.indexOf('lesManage') > -1) { router.push({ path: "/lesson" }) } else if (domClassName.indexOf('claManage') > -1) { router.push({ path: "/class" }) } } }) } </script> </body> </html>
新建一個html文件,將代碼複製過去便可運行。能夠嘗試點擊按鈕切換路由,或者手動輸入路由進行切換。
下面逐步解讀代碼,瀏覽器
1.首先來看,最核心的就是Route構造函數以及爲Route添加原型方法。
Route構造函數中作了兩步操做,1.接收參數。2.調用原型上的init初始化方法。
再來看原型上的兩個方法,服務器
window
對象的hashchange
事件添加監聽,那何時會觸發hashchange
事件呢。我在上面已經解釋了什麼是hash值,那麼當hash
值發生改變的時候,就會觸發hashchange
事件,事件對象能夠拿到oldURL
和newURL
兩個屬性,分別表明改變前的url和改變後的url。固然也能夠經過window.location.hash
直接拿到hash值(包含#)。拿到hash
值後要作的就是遍歷傳入的路由配置參數,若是有匹配的hash
值就執行對應的操做。hash
值。2.調用Route構造函數實例化一個route對象var router = new Route()
,參數就是咱們的路由配置。配置中path
就是改變的hash值,component
就是匹配到hash值後進行的操做,也就是咱們上面定義的changePage
函數。less
3.在點擊按鈕的時候調用router.push({ path: "/student" })
就能夠改變url的hash值,值改變了就觸發了window的hashchange事件,也就執行了咱們定義好的changePage
函數。dom
這就是一個簡單的hash路由的實現,示例不夠完善,只是做爲學習原理的一個參考。若有問題感謝指出。ide