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

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. 事件委托(event delegation)

    事件委托给我带来的第一印象是,如果可以的话请尝试得经常使用它,性能好! 通过字符串拼接后,并进行DOM插入,不会复制事件,此时需要进行事件委托了!!! 优点 事件委托对于web应用程序的性能有如下几个 ...

  2. HTML5每日一练之figure新标签的应用

    igure元素是一种元素的组合,可带有标题(可选).figure标签用来表示网页上一块独立的内容,将其从网页上移除后不会对网页上的其他内容产生影响.figure所表示的内容可以是图片.统计图或代码示例 ...

  3. POJ 1410 Intersection(判断线段交和点在矩形内)

    Intersection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9996   Accepted: 2632 Desc ...

  4. 应用TcpListener实现的socket服务器端

    前言 项目中要实现一个简单的socket服务器端,采用了TcpListener这个类.除了基本的功能之外,有几处需要注意的点. 要能同时接收多个客户端的连接,当然,不需要几千个那么多. 要能探测到客户 ...

  5. My集合框架第三弹 AVL树

    旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对 ...

  6. RecyclerView 下拉刷新上拉加载

    步骤: 首先直接定义一个XRecyclerView继承RecyclerView,重写他的三个构造方法. init(Context mContext)方法用来初始化底部加载的view 回到XRecycl ...

  7. Intent 传数据

    Intent作为android重要的组件其重要性不言而喻,这里说说他是怎么传递简单数据和对象 Intent的具体概念就不讲解了!网上有很多的 传递简单的数据(例如String,float等) 传递对象 ...

  8. android Intent的startActivityForResult()方法

    startActivityForResult() 之前学习了利用Intent跳转页面的同时传值,但有的时候需要从跳转到的页面返回所需要的值(如修改了用户信息,需要返回修改的信息),通俗的意思就是A.A ...

  9. TCP客户机-服务器

    1 僵尸进程 2 信号处理 信号: 1 由一进程发往另一进程 2 由内核发往某进程   僵尸状态: 父进程取回子进程的相关信息,进程的ID,终止状态,子进程的资源利用信息   编程时: 1 当派生子进 ...

  10. StringUtils 字符串工具类

    package com.thinkgem.jeesite.common.utils; import java.io.File; import java.io.IOException; import j ...