本篇内容是在上一次的基础上进行改进,对状态的定义进行了修改,一个状态的定义以下: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