本篇內容是在上一次的基礎上進行改進,對狀態的定義進行了修改,一個狀態的定義以下:javascript
function state(stateName, template, templateUrl) { this.stateName = stateName; if (template) { this.template = template; } if (templateUrl) { this.templateUrl = templateUrl; } }
即每個頁面對應着一個狀態,一個狀態有一個狀態名,還有一個模板/模板url,這樣咱們就能夠將不一樣頁面的內容寫到不一樣的html裏,而後經過templateUrl將他們動態加載進來渲染頁面。css
先貼上js代碼:html
var states = []; var currentState; $(document).ready(function() { registState(); console.log(states); currentState = init(); //監聽hash路由變化 window.addEventListener("hashchange", hashChange) }) //哈希路由處理事件 function hashChange() { var nextState; console.log(window.location.hash); //判斷地址是否爲空,若爲空,則默認到main-view頁面 if (window.location.hash == "") { nextState = "mainView"; } else { //若不爲空,則獲取hash路由信息,獲得下一個狀態 nextState = window.location.hash.substring(1); } //判斷當前狀態是否註冊過(是有存在這個狀態)0g var validState = checkState(states, nextState); //若不存在,則返回當前狀態 if (!validState) { createState(nextState, "", "./test.html"); currentState = nextState; return; } $('#' + currentState).remove(); if (!nextState.view) { states.forEach( function(element, index) { if (element.stateName == nextState) { createView(element); } }); } currentState = nextState; } //狀態註冊 function registState() { var newState = new state("mainView", "", "./main-view.html"); var newState1 = new state("listView", "", "./list-view.html"); var newState2 = new state("detailView", "", "./detail-view.html"); states.push(newState); states.push(newState1); states.push(newState2); } //初始化,對用戶一開始輸入的url進行處理 function init() { nextState = window.location.hash.substring(1); //若用戶輸入的hash值爲空,則默認跳轉到states[0]的頁面 if (nextState == "") { createView(states[0]); return states[0].stateName; } states.forEach( function(element, index) { if (element.stateName == nextState) { createView(element); } }); return nextState; } //判斷狀態是否存在 function checkState(states, nextState) { var tof = false; states.forEach(function(element) { if (element.stateName == nextState) { tof = true; } }) return tof; } //建立一個狀態 function createState(stateName, template, templateUrl) { var newState = new state(stateName, template, templateUrl); createView(newState); $("#" + newState.stateName).css("display", "block"); $('#'+ currentState).css("display", "none"); currentState = newState; states.push(newState); } //建立狀態所對應的視圖,並將視圖放到body裏 function createView(state) { if (state.template) { template = state.template; state.view = $("<div id='" + state.stateName + "'></div>").html(template); $("body").append(state.view); } else if (state.templateUrl) { htmlobj = $.ajax({url: state.templateUrl, async: false}); template = htmlobj.responseText; state.view = $("<div id='" + state.stateName + "'></div>").html(template); $("body").append(state.view); } } //狀態對象 function state(stateName, template, templateUrl) { this.stateName = stateName; if (template) { this.template = template; } if (templateUrl) { this.templateUrl = templateUrl; } }
裏面沒有任何東西,內容都是咱們動態加載進去的java
<!DOCTYPE html> <html> <head> <title>SPA</title> <link rel="stylesheet" type="text/css" href="index.css" /> <script type="text/javascript" src="jquery-3.1.1.min.js"></script> <script type="text/javascript" src="spa.js"></script> </head> <body> </body> </html>
我使用的是chrome瀏覽器,因爲安全問題,chrome必須經過http等方式才能用$.ajax來獲取到文件內容,所以我用了nodejs的http-server本身搭建了一個簡單的服務器.
其餘的頁面都只是單純的html文件,沒有什麼特別,因此就不列舉出來了node
輸入服務器的url
修改url,在後面加上#listView(以前在初始化的時候就已經註冊過的狀態)
輸入一個沒有註冊過的狀態(註冊了一個默認的狀態)
jquery
接下來打算作一下嵌套狀態,若是有什麼好的建議,麻煩告訴下我~~ajax