一、前言
单网站页面设计开发在目前的WEB设计开发中占有绝对的优势,单页面应用可以 提高用户体验度,可以 维持混合开发应用软件开发。要维持单网站页面设计开发都是很多 前端框架,例如:AngularJS,BackboneJS这些,这些都是很流行很全面的前端开发框架,它提供了网页模板,路径解析,API访问及Dom操作功能,但是有时候我们的需求比较简单,如果用这些大型前端框架那就显得有点重了。这里我介绍下自己使用Jquery实现单页面应用开发的过程。
二、URL HASH理解
Html中的锚点定位相信大家都用过,在URL中,“#” 与其后面的字符串共同组成了锚点部分,“#” 代表网页中的一个位置,其右面的字符,就是该位置的标识符。单单改变 “#” 后的部分,浏览器只会滚动到相应位置而不会重新加载网页,在JavaScript中我们通过location.hash来获取。在URL中,除了以 “#” 号开头锚点部分,还有一段以“?”号开头的部分,“?”及后面的字符串代表的是传递的参数,在 “http” 请求中,“#” 及标识符是不会传递到服务器的,而“?”后面的参数部分则会发送到服务器。
接下来我们用几个URL来理解下:
1、http://www.xxx.com/a/b#a
2、http://www.xxx.com/a/b#a?name=XX&age=21
在这两个URL中,“#a” 就是hash,我们称之为path部分,“?name=XX&age=21”我们称之为search部分。接下来我们再看个URL:
这个URL跟上面的第一个URL有一个区别,多了一个 “!” 相信大家在单页面应用开发的时候都看到过 “#!” 的组合,为什么要如此组合?大家可以看下谷歌的一篇文章(Making AJAXapplications crawlable)大概的意思就是说让path部分可以被搜索引擎搜索到,而search部分是不能被搜索的,这点很重要,如果你做的页面不能被搜索引擎搜索到那就没意义了。
三、案例
现如今很多流行的前端框架都是单页面应用,但是有时候我们的需求比较简单,又不想用那些大型的前端框架,怎么办?比如:一个公司有公司的官网,公司官网一般是静态页面,然后里面有个注册功能,但是注册呢是分几个步骤的,又不想在一个页面显示完成,现在的网页一般都需要设计的简洁,不然太繁琐了人家一看都懒得填了,注册到下一个步骤需要记录上一个步骤的数据,而且用户回退的时候还会自动记住用户上一个步骤填入或选择的数据,这个时候大家肯定会想着在一个页面上用简单的显示和隐藏元素来实现,实际上大多数都是这样做的,但是有一个缺点,用户点击浏览器的前进和后退怎么办?这样做的情况下用户点击前进和后退就退出了注册页面了,如何避免这种情况呢?下面介绍的单页面开发就可以解决这个问题。那在这里如何开发我们的单页面应用?显然用AngularJS这种大型的前端框架并不合适,这个时候别忘记了我们的老朋友-jQuery。
四、单页面开发
在进入开发步骤之前,我们先了解下一个jQuery的框架-jquery-hashchange。这个框架就是用来做路由控制的,它可以监听hash的变化。
假如我们的需求有两个步骤,我们写一个路由控制的类,这个类我们学习下AngularJS的route模块定义方式,将模板和控制器定义在一起:
/**
* 路由模块,获取当前加载的模板序号 */ Route = (function() { var _getCurrentPath, _pathRegu, _pathRoute, _rootPath; _rootPath = '#!regist'; _pathRegu = /#!regist/w+/g; _pathRoute = { "default": '/one', paths: [ { url: '/one, templateId: 'page-1', controller: 'PageOneCtrl' }, { url: '/two, templateId: 'page-2', controller: 'PageTwoCtrl' } ] }; _getCurrentPath = function() { return location.hash.substring(_rootPath.length); }; return { rootPath: _rootPath, initPath: function() { var currentPath; if (location.hash.indexOf(_rootPath) !== 0 || location.hash.match(_pathRegu).length === 0) { window.location.href = _rootPath + _pathRoute["default"]; return true; } currentPath = this.getCurrentPath(); if (!currentPath) { window.location.href = _rootPath + _pathRoute["default"]; } }, getCurrentPath: function() { var currentPath, i, _path; currentPath = _getCurrentPath(); _path = null; i = 0; while (i < _pathRoute.paths.length) { if (_pathRoute.paths[i].url === currentPath) { _path = _pathRoute.paths[i]; break; } i++; } return _path; }, getTemplateId: function() { var _path; _path = this.getCurrentPath(); if (_path) { return _path.templateId; } else { window.location.href = _rootPath + _pathRoute["default"]; } }, href: function(_url) { window.location.href = _rootPath + _url; } }; })(); |
这段代码是路由模块,我们先定义了一个根路由:_rootPath = '#!regist';,而后我们定义了一个跟路由匹配正则_pathRegu= /#!regist/w+/g;,这个正则在后面做路由匹配有用。接下来我们看路由定义_pathRoute对象,该对象定义了一个默认路由default和一个路由定义的数组path,在path里面每个路由都定义了路由地址,模板id和控制器,这里的模板使用的是jquery-tmpl插件,接下来我们看看控制器类:
PageOneCtrl = (function(route) {
//这里写第一个页面的详细逻辑 })(Route) PageTwoCtrl = (function(route) { //这里写第二个页面的详细逻辑 })(Route) |
然后我们要看看模板定义:
<script id="page-1" type="text/x-jquery-tmpl">
<div>第一个页面模板</div> </script> <script id="page-2" type="text/x-jquery-tmpl"> <div>第二个页面模板</div> </script> |
好,到这里我们就看到了控制器类定义和页面模板定义,下面我们再看看如何将控制器和模板进行解析:
PageStep = (function(route) {
/** * 加载页面模板 */ var _loadContentTmpl; _loadContentTmpl = function(cb) { //_selector.container是插入模板容器的jquery对象 //将当前路由的模板插入到页面模板容器中显示 _Seletor.container.html($('#' + route.getTemplateId()).tmpl()); if (cb && typeof cb === 'function') { cb(); } }; return { init: function() { route.initPath(); _loadContentTmpl(function() { var currentPath, f; currentPath = route.getCurrentPath(); f = eval(currentPath.controller); f.init(); }); } }; })(Route); |
这个类是总控制器,它负责路由转发和模板加载,最后我们还要使用jquery-hashchange插件监听路由变化来转发路由和加载模板:
$(document).ready(function() {
$(window).hashchange(function() { PageStep.init(); }); $(window).hashchange(); }); |
这样,我们用jQuery实现单页面应用开发的基本模块就搭建完成了,在前端开发中,我们常要跟服务器通信,这个时候我们可以专门写一个类做接口调用,如:
RegistApi = (function() {
return { regist: function(_data, cb) { var _params; _params = { a:_data.a }; $.post('/xxx/yyy', _params, (function(data) { if (data) { if (cb && typeof cb === 'function') { cb(data); } } }), 'json').error(function() { if (cb && typeof cb === 'function') { cb({err: true}); } }); } }; })(); |
然后在控制器中引入该模块,调用相应的接口函数就好了。
本文来源于:【技术干货】前端开发之jQuery单页面开发-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
- 加入Q群
- QQ扫一扫
评论