市面上有大量的SPA框架,如AngularJs, backbone, Knockout等,對於追求極致小得移動端來說, 都比較大,重!
正在苦惱的時候,我們的wikieswan解決了這一問題。github地址:vipspa
使用方法非常的簡單:

1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8" > 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> 6 <meta name="msapplication-tap-highlight" content="no"> 7 <meta content="yes" name="apple-mobile-web-app-capable"> 8 <meta content="black" name="apple-mobile-web-app-status-bar-style"> 9 <meta content="telephone=no" name="format-detection"> 10 <title>vipspa demo</title> 11 <link rel="stylesheet" type="text/css" href="css/main.css"> 12 13 </head> 14 <body> 15 <ul> 16 <li><a href="#home">首頁</a></li> 17 <li><a href="#content">公司簡介</a></li> 18 <li><a href="#contact">聯系我們</a></li> 19 </ul> 20 <div id="ui-view"></div> 21 <script type="text/html" id="error"> 22 <!--可以自定義錯誤信息--> 23 <div> 24 {{errStatus}} 25 </div> 26 <div> 27 {{errContent}} 28 </div> 29 </script> 30 31 <script type="text/javascript" src="lib/zepto-1.1.4.min.js"></script> 32 <script type="text/javascript" src="lib/vipspa.js"></script> 33 <script type="text/javascript" src="js/require.vipspa.config.js"></script> 34 </body> 35 </html>
github 上有詳細的使用介紹,在此不再贅述。
下面我們研究下源碼。
首先看下基本的代碼結構:

1 (function() { 2 // 構造函數 3 function Vipspa(){ 4 5 }; 6 7 //中間部分 8 Vipspa.prototyp = { 9 //.... 10 }; 11 12 window.vipspa = new Vipspa(); // 當然這塊可以提取出來 13 }();//這塊也可以做繼續的改進
這是一個簡單的模型模式。其中運用了匿名閉包,我們將簡單的創建匿名函數,並立即執行。所有函數內部代碼都在閉包內。它提供了整個應用生命周期的私有和狀態。
如果我們想進一步擴展的話,可以把window.vipspa = new Vipspa();提取出來做進一步的擴展。
然后我們追蹤構造函數原型的原型方法。

1 var routes = { 2 view: '#ui-view', 3 router: { 4 'home': { 5 templateUrl: 'views/home.html', 6 controller: 'js/app/home.js' 7 }, 8 'content': { 9 templateUrl: 'views/content.html', 10 controller: 'js/app/content.js' 11 }, 12 'contact': { 13 templateUrl: 'views/contact.html', 14 controller: 'js/app/contact.js' 15 }, 16 'defaults': 'home' //默認路由 17 } 18 };

1 vipspa.start(routes);
是不是看上去有點熟悉,是的,就像 angularJs中的 ui-route 插件
好了看下Vipspa.prototype.start

1 var self = this;
這里可能會有疑問:為什么非得把this保存起來呢?這是因為,內部函數(比如本函數里面包含的兩個匿名函數)
在搜索this變量時,只會搜索到屬於它自己的this,而不會搜索到包含它的那個函數的this。
所以,為了在內部函數能使用外部函數的this對象,要給它賦值了一個名叫self的變量。
在 self 對象 中 設置了 routerMap(routes中的router) 和 mainView(routes中的view) 屬性
然后執行startRouter函數,當錨部分發生變化時(window.onhashchange)再次執行startRouter函數
下面我們看startRouter函數做了什么?

1 var hash = location.hash; 2 var routeObj = vipspa.parse(hash); 3 routerAction(routeObj);
這里需要說明下:
1.location是javascript里邊管理地址欄的內置對象,比如location.href就管理頁面的url,用location.href=url就可以直接將頁面重定向url。而location.hash則可以用來獲取或設置頁面的標簽值。比如http://domain/#admin的location.hash="#admin"。利用這個屬性值可以做一些非常有意義的事情。
2.vipspa.parse(hash) 解析獲取到得hash值
3. 執行關鍵函數 routerAction();
在 routerAction 中做了什么事情呢?
我們點擊URL時希望做什么事情呢?,當然是執行該路由對應的html和js
我們通過ajax請求

1 <div id="ui-view"></div>
刷新該視圖,並加載對應的js(routerItem.controller)怎么加載對應的js呢?通過loadScript方法
通過腳本創建一個<script>元素,地址指向routerItem.controller,可在callback函數中執行所傳入的數據。
該方法也可用於JSONP中得跨域。
好了,這個微框架先介紹到這里,歡迎大家指正和吐槽。