出处:http://my.oschina.net/neo600/blog/51529
在我们开发网页应用时需要使用许多技术工具。我最近已经重新开始写网页应用程序了,并且想把我以前在开发周期过程里所记录的零散想法都联系起来。这篇帖子主要介绍我找到的几个框架,它们对于我最近的几个项目都非常有帮助。我接下来主要讲解最关键的一些框架,它们每一个都能扩展成独立的文章。我并不是要对当前存在的各种框架进行大范围的比较,仅仅是把我最近尝试过的技术分享一下。
虽然本文的主题主要针对移动开发,不过我认为这些技术也适用于一般的网页应用。我的所有决定和数据点都符合以下几点:
只支持JavaScript(CoffeeScript和Dart是否兼容还有待观察,不过我会尽量避免选择它们而引发的异常)
在最新的移动浏览器里运行正常(如iOS 5, Android 4)
选择MVC(模型-视图-控制器)方案
模型-视图-控制器方案用在自然界面的应用的开发里已经数十年了。其基本思路是分离数据层(存储,通讯,数据)和表示层(用户界面,动画,输入)。虽然有其它类似的模式,例如MVVM(Model View ViewModel),但是最主要的想法是要在表示层和数据层之间有明确区别,使得代码能够更加简洁和稳定运行。
目前已经有众多JavaScript模型―视图―控制器框架可以使用。其中一些,如Backbone.js和Spine.js,都使用纯代码编写,而另外一些,像Knockout.js和Angular则需要DOM数据绑定属性。对分离视图和数据的MVC系统来说,依托HTML5的数据和DOM属性似乎有些不妥。因此我不使用Knockout和Angular框架。基于我的原始需求,Spine.js用CoffeeScript来写比较简单。
对于大部分框架来说,Backbone.js的使用时间更长(可能除了JavaScriptMVC,一个停用的项目),还拥有越来越多的开源社区。我的应用程序栈一直使用Backbone.js。为了得到更多选择MVC的信息,我查看了TodoMVC,它实现了相同的Todo应用程序使用不同的MVC框架。你也可以看看 MVC framework comparison这篇文章,它推荐Ember.js这个场景里的新文件。我还没有机会使用它,但是它在我的计划之中。
选择一个模板引擎
如果想要在网络上建立一个真正的应用程序,你不可避免地要建立大型DOM树。相对使用JavaScript API操作DOM,它可以更简洁高效地使用基于字符串的模板,而不是写HTML。一般来说,JS模板已经发展到使用奇怪的常规脚本,它在脚本标记内嵌入模板内容:<script id="my-template" type="text/my-template-language">...</script>
。使用所有模板引擎的基本模式是把模板作为一个字符串来加载并构建模板参数,然后通过模板引擎运行模板和相关参数。
Backbone.js依赖于Underscore.js,它是一种复杂语法写的受限模板引擎。此外,还有其它模板可供选择,例如jQuery Templates,Handlebars.js,Mustache.js。JQuery团队开发的jQuery模板已经过时了,所以我没有考虑它。Mustache是一个跨语言的模板系统,它的特点是简单并且成熟,可以支持尽可能简单的逻辑。事实上,Mustache中最复杂的构造是一种遍历对象数组的方法。Handlebars.js相当依赖Mustache,它加入了一些不错的功能,如预编译模板和模板表达式。对我而言,我并不需要这些附加功能,也不必选择Mustache.js作为我的模板平台。
一般来说,我认为现有的模板框架在功能上差别都不大,因此选择哪个在很大程度上是个人喜好问题。
选择一个CSS框架
CSS框架是必不可少的工具,它使用便利功能(如变量)扩展CSS的功能集。这是一种创建分层CSS选择器和一些更先进的功能的方法。这样做实质上是创建了一种新的语言:CSS增强版(暂且叫它CSS++)。为便于开发,一些框架在浏览器中执行一个JavaScript编写的CSS++解释器,而其他框架则让你监控一个CSS++文件,并在有任何更改的时候编译它。所有的CSS框架都应提供命令行工具把CSS++编译成CSS来部署。
就像模板语言一样有很多功能相似的选择。我的选择是出于个人的语法偏好。我更喜欢SCSS,因为它避免了怪异的语法(如@)。SCSS的缺点之一是:它并没有附带一个JavaScript解释器(有一个非官方的解释器,但是我没有试过),只使用一个命令行观察器。其它类似的CSS框架,包括LESS和Stylus。
如何布置视图
HTML5提供了多种方式来布置内容,但MVC框架并没有提供使用这些布局技术的建议,这有时让程序员们很难做出决定。
一般来说,相对定位比较适合文档,但不适用于应用。显然,绝对定位应尽量避免,尤其是表格布局。许多Web开发人员已经转向使用浮动属性对齐元素,但这并不是构建应用程序视图的最佳方法,因为它没有优化类似于应用程序的布局,从而导致许多奇怪的问题和infamous clearfix hacks。
多年来,经过对各种网络布局技术的实验,我认为一个固定位置和flexbox模型相结合的移动互联网应用是一个理想的选择。我使用的固定位置是固定在屏幕上的界面元素(标题,侧边栏,页脚等等)。Flexbox模型则非常适合在页面(水平或垂直方向)上布置层叠视图。它是唯一为界面设计明确优化的CSS盒模型,与Android的Linearout管理颇为相似。有关flexbox模型的更多信息,请阅读Paul的文章,并注意该规范被替换为一个新的且不向下兼容的版本。
自适应Web应用程序
最后一节是关于这一问题:我大力提倡创建设备特定的用户界面。这意味着需要根据不同的情况重新编写视图代码部分。幸运的是,MVC模式使得重复使用多个视图(如平板电脑和手机)的单一模式更加简单。
IOS上的Flipboard软件很好的演示了这一设想,它为平板电脑和手机用户的不同设备尺寸提供了相应的开发经验。
手机界面进行优化以便单手垂直滑动。
平板电脑的界面方便双手从不同方向操作。
输入注意事项
处于移动状态时,用户与应用程序的主要交互方式是用手指触摸屏幕。这与使用鼠标的交互不同,由于屏幕上有额外的9点需要跟踪,开发人员在编写移动应用程序时尽量少使用鼠标事件。此外,鼠标事件在移动中点击有300ms延迟的问题(有一个著名的touch-based解决方法)。有关使用移动浏览器时这些事件的更多详细信息,请参阅my touch events article这篇文章。
仅仅靠s/mousedown/touchstart/
使用你所有的事件处理程序是不够的。用户希望能够靠一套全新的手势使用触摸设备,比如在屏幕上滑动,例如浏览图像列表。虽然苹果公司有一个鲜为人知的gesturesAPI,但却没有一套网络上开放的手势检测规范。事实上我们需要一个JavaScript库以便于识别一些常用手势。
如何使其脱机工作
为了让一个应用程序脱机工作,你需要做两件事情:
1.资源可用(通过AppCache,Filesystem API等等实现)
2.数据可用(通过LocalStorage,WebSQL,IndexedDB等等实现)
实践中,在网络上构建脱机应用是一个棘手的问题。一般来说脱机功能一开始就应该在应用程序中构建。如果不重写重要代码很难让现有的网络应用程序脱机工作。此外,各种脱机运行技术常常受到未知存储的限制,并且无法确定超出限制时会发生什么不可预料的情况。最后,还有一些脱机技术问题,尤其是AppCache,正像我在先前的文章中描述的。
编写能够真正脱机运行的应用程序有一个非常有趣的方法:“先脱机”。换句话说,你写的一切都是在没有网络连接的情况下运行的,只有同步数据需要网络连接。在Backbone.js MVC模型中,这可以很好地适应自定义Backbone.sync适配器。
单元测试
一般来说,你的用户界面很难进行单元测试。但如果你使用MVC模型完全隔离用户界面,那么测试将变得简单。Qunit是一个相当不错的选择,特别是它允许使用它的start()和stop()方法对异步代码进行单元测试。
总结
总之,我使用Backbone.js MVC,Mustache.js模板,SCSS作为CSS框架,CSS Flexbox渲染视图,自定义触摸事件,Qunit完成单元测试。通过这些编写我的移动网络应用程序。关于脱机支持,我仍将尝试使用各种技术实现,并在以后的文章中介绍它们。虽然我相信这里列出的每类工具(如MVC)十分必要,但我也承认本文中描述的许多技术是通用的(如Handlebars和Mustache)。