### 閑話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的很多設計思想都非常棒,包括其中有我非常看好的組件化編程模式,不過遺憾的是比較復雜,我到目前都沒能很好的掌握,我希望可以考慮優化一下,減小組件的編寫難度。