本篇内容是在上一次的基础上进行改进,对状态的定义进行了修改,一个状态的定义如下:

function state(stateName, template, templateUrl) {
this.stateName = stateName;
if (template) {
this.template = template;
}
if (templateUrl) {
this.templateUrl = templateUrl;
}
}

即每一个页面对应着一个状态,一个状态有一个状态名,还有一个模板/模板url,这样我们就可以将不同页面的内容写到不同的html里,然后通过templateUrl将他们动态加载进来渲染页面。

先贴上js代码:

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;
}
}

处理逻辑

  1. 一开始进入页面的时候,先利用registState()注册一些状态,然后利用init()函数来对用户一开始输入的url进行处理
  2. 当用户输入的路由发送变化的时候,调用hashChange()函数:
    1. 获取用户输入的hash值,这个hash值即为状态名
    2. 检查这个状态是否已经注册,若已经注册过,则将当前的页面内容清除掉,然后为输入的状态创建视图
    3. 若状态未注册,则创建一个新的默认状态

文件结构如下:

index.html里的内容

里面没有任何东西,内容都是我们动态加载进去的

<!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文件,没有什么特别,所以就不列举出来了

截图

输入服务器的url



修改url,在后面加上#listView(之前在初始化的时候就已经注册过的状态)



输入一个没有注册过的状态(注册了一个默认的状态)

接下来打算做一下嵌套状态,如果有什么好的建议,麻烦告诉下我~~

SPA初试-1的更多相关文章

  1. SPA页面初试

    之前一直很好奇,SPA应用到底是怎么实现的,昨天无意间看到了有一篇介绍的文章,就想着来试一下水(以下根据我的理解所写,可能会让你看的云里雾里,如果想加深了解,最好先了解下window.location ...

  2. BI分析受阻?FineBI推出SPA螺旋式分析新功能!

    过去,企业级的数据分析通常会有这么几种场景,业务部门托信息部门分析数据,结果报表一出,唇枪舌剑争论你我高低,数据不准,指标不对.信息部门欠缺业务概念,业务部门不懂技术逻辑,数据分析之路,暂时搁浅. 后 ...

  3. 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...

  4. 如何快速开发SPA应用

    前言 web早已经进入了2.0时代了,如今的网页大有往系统应用级别的方向发展的趋势,再也不是以前的简单展示信息的界面了.如今很多webapp已经做到了原生应用的功能,并且运用自身的优势逐步取代之.HT ...

  5. 使用backbone的history管理SPA应用的url

    本文介绍如何使用backbone的history模块实现SPA应用里面的URL管理.SPA应用的核心在于使用无刷新的方式更改url,从而引发页面内容的改变.从实现上来看,url的管理和页面内容的管理是 ...

  6. AngularJS SPA Template For Visual Studio

    单页面应用程序(SPA)[使用JavaScript.CSS和HTML强大的功能,可以构建一个单页面应用程序(SPAs)],它提供了丰富的用户体验页面.导航技术和AJAX提供必要的功能,而不用重新加载页 ...

  7. 移动前端开发-单页应用(spa)模型

    一门新的技术诞生总会引来一番争议,单页Web应用程序也不例外,其最大的优势在于用户体验,对于内容的改动不需要加载整个页面:对服务器压力很小,消耗更少的带宽,与面向服务的架构更好地结合.使用HTML+C ...

  8. caffe初试(一)happynear的caffe-windows版本的配置及遇到的问题

    之前已经配置过一次caffe环境了: Caffe初试(一)win7_64bit+VS2013+Opencv2.4.10+CUDA6.5配置Caffe环境 但其中也提到,编译时,用到了cuda6.5,但 ...

  9. Single-page app(SPA)

    有哪些值得推荐的一页式网站(Single-page app)? http://pro.weltrade.com/en/ 最近开到一下国外网站,一页到底,感觉很高大上,到底是怎么做出来的呢?技术要点是什 ...

随机推荐

  1. delphi请求idhttp数据

    idhttp ss : TStringStream; begin ss := TStringStream.)); { 指定gb2312的中文代码页,或者54936(gb18030)更好些 utf8 对 ...

  2. oracle 去掉空格

    trim(value) 去掉左右空格 ltrim(value) 去掉左空格 rtrim(value) 去掉右空格

  3. New Objective-C Feature

    [Advance Objective-C Feature] 1.@import避免反复解析头文件,本地宏对框架API定义无影响. 2.可以导入单独一个头文件. 3.使用了@import后,不再需要选择 ...

  4. python知识点(07-08)

    python: 循环else: while true: if x>1: print() break else: print() 文件循环: for line in open(‘test.txt’ ...

  5. oracle学习 八 分页(使用rownumber)(持续更)

    rownumber是查询的数据集之后加入一个伪列(连续的)使用它可以去制作以oracle数据库为基础的分页,语句类似于公式直接套用如下: select * from (select rownum r, ...

  6. C#用串口接收事件接不全数据的处理

    问题描述:都知道用事件dataReceive来处理串口非常的方便,但当一次的数据过长时,就会出现截断数据的情况.比如说发一个指 令,返回一个30个字节的数据,但上位机则分两次来接收者30个数据. 解决 ...

  7. 浅析 JavaScript 中的闭包(Closures)

    a { text-decoration: none; color: #4094c7 } h4,h5 { margin: 0; font-weight: 700; color: inherit; lin ...

  8. yii2.0 gii

    1.添加模型 ./yii-dev gii/model --tableName=tableName --generateLabelsFromComments --ns='app\models\base' ...

  9. linux TCP数据包重传过程----小结

    于TCP/IP协议栈的TCP协议的重传功能是由在linux内核源码(net/ipv4/tcp_output.c)中的函数tcp_retransmit_skb()实现的 代码如下: /* This re ...

  10. android 小方法

    小方法 1.获取屏幕分辨率: public class BaseTools { public static int getWindowWidth(Context context) { // 获取屏幕分 ...