### 闲话js前端框架
前端人员=美工+设计+代码+测试
——题记
**专题文章:**
一、从avalonjs的模板说起
二、庞大的angularjs
三、再也不想碰DOM
四、组件化?有没有后端的事?
五、再看自己一年前设计的微型渲染引擎
六、在浏览器标准上做文章
七、抛开浏览器,构建应用容器
八、为何Flash、银光和Java都在网页端一蹶不振
本文属 西风逍遥游 原创, 转载请注明出处: 西风世界 [http://blog.csdn.net/xfxyy_sxfancy](http://blog.csdn.net/xfxyy_sxfancy)
### 一、从avalonjs的模板说起
我开发网站的时间,已经一年多了,其实一直是作为后端人员在工作着。但不幸的是,我对数据库的维护啥的兴趣不大,而且很喜欢华丽的界面效果,于是在偷偷地关注着前端的一举一动。
就我个人而言,我并不喜欢网站这种模式,我喜欢的是精品的应用,功能强大,操作方便的桌面GUI,或者是好用简洁的手机应用。联网应用一开始就给我一种卡顿、缓慢的感觉,而且重度依赖网络。但后来,我发现,这只是我个人的偏见而已,没人规定联网应用就会卡顿,没人说联网应用就不能离线工作。当然,这也是近来,越来越多的桌面程序和手机应用,开始转向html5开发,大势所趋。
### 初级网站的尴尬
在去年,我接触了jQuery后,学会了动画、dom操作、ajax,觉得网站可以上手了,于是开始用php+jquery搭建了我的第一个小网站。当前学的第一款php框架phalcon,使用了大量后端模板,创建整个项目。
正在我乐此不疲的寻找一款又一款jQuery插件时,我发现了尴尬的问题。不同种类的jQuery插件,搅到一起,简直就是人间地狱。。。我想制作一个后台功能,将一个树状拖放型控件,在放置结束后,弹出一个对话框,然后在对话框中设定一些功能。这个任务我做了三天都没弄出来,虽然最后用来大量无比恶心的jQuery事件绑定+解绑才终于让它正常工作起来,但我已经不想再去看那些恐怖的jQuery代码了。
说到底,问题只有一个,js的组织方式不对,基于事件监听及回调的工作方式,必然会使得所有的js函数呈现扁平化趋势,就是说所有的js函数都在同一层相互调用,你很难搞懂那些代码是属于哪部分功能的。**结果就是,整体的耦合性非常高**。
### 三天的思考
项目完工后的三天,我什么都没做,就思考了这个问题三天。我想,网页端很难进行复杂逻辑的开发,但桌面GUI并没有发现这么难以设计,应该在于组件化的问题。WEB应用由于设计所限,组件化是十分困难的。一段HTML代码,不但依赖当前的CSS环境和JS环境,甚至浏览器不同都会造成一定的差别。
为了实现组件化,那么就要考虑封装,将恐怖的内容封装在模块内部,将优雅的接口展现于外部,这就是封装的精髓。
决定后,于是我开始动手实践。我开始写了一款非常小巧的,层级渲染引擎,我把它命名为ntml。准确的说,这并不是一款前端模板引擎,而更像是后端模板引擎,这款有着独特语法的引擎让我大致有了在前端进行模块化开发的思路,之后的文章中,我会再次提起那非常有趣的设计。
### 司徒正美大神的框架
前端模块化,带着这个问题,我去寻找别人的帮助。我们的科技导员张野同志,真的很厉害,我去问他这方面的问题时,他首推给我们的解决方案就是angularjs,当然还有requirejs和extjs。
这时,我发现我推开了前端的大门,我逐渐接受前端人才会思考的概念。我也装上了nodejs,npm包管理,grunt构建,了解了AMD加载器,CSS的hack等等,但当时,我并没有学习angularjs,extjs,毕竟这些库是变态级别的大!对于喜欢精简的我,这种庞大的项目是不大对胃口的(正如相比QT,更喜欢用gtk;相比Python、Ruby,更喜欢lua),于是我挑中了avalonjs这款轻量级的前端模板库,也了解了国内的前端大神司徒正美。
看了avalon的设计,觉得非常不错,很快就用到了各种网站项目中了。为了更深入的了解底层框架结构,我还专门买来司徒正美的书《javascript框架设计》来学习。
我发现,前端框架最大的优势,就是将前端开发变成了类似传统客户端程序的开发方式,逐渐减少了页面跳转,甚至直接变成了单页模式,不跳页的WEB应用,正在向在原生应用靠拢。
### avalonjs利器
阿瓦隆(avalon)是亚瑟王传说中,亚瑟王长眠的神秘岛屿。而avalonjs,也正如他的名字一样,是一个很让人期待的理想乡。下面就来看一下司徒正美给的基本的avalon的例子:
~~~
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="avalon.js"></script>
</head>
<body>
<div ms-controller="box">
<div style=" background: #a9ea00;" ms-css-width="w" ms-css-height="h" ms-click="click"></div>
<p>{{ w }} x {{ h }}</p>
<p>W: <input type="text" ms-model="w" data-event="change"/></p>
<p>H: <input type="text" ms-model="h" /></p>
</div>
<script>
avalon.define("box", function(vm) {
vm.w = 100;
vm.h = 100;
vm.click = function() {
vm.w = parseFloat(vm.w) + 10;
vm.h = parseFloat(vm.h) + 10;
}
})
</script>
</body>
</html>
~~~
这种模式,叫做动态模板,是区别于传统静态模板的工作方式。以前有很多前端模板,就是就是给一段text文本,然后将里面的内容进行替换,替换后就直接当做html的内容放到dom中。这样做是很不好的,静态模板虽然简单,但他的最大缺点是更新html代码时,重建了dom树,这样就使得原来注册过的事件没了。
于是这种模板的工作,往往是直接将模板写成可读的html代码,然后遍历dom树,然后依次解析各个节点。需要添加内容的,或者需要修改元素时,只操作dom树上最少的部分就可以了。
avalon的很多设计思想都非常棒,包括其中有我非常看好的组件化编程模式,不过遗憾的是比较复杂,我到目前都没能很好的掌握,我希望可以考虑优化一下,减小组件的编写难度。