市面上有大量的SPA框架,如AngularJs, backbone, Knockout等,對於追求極致小得移動端來講, 都比較大,重!javascript
正在苦惱的時候,咱們的wikieswan解決了這一問題。github地址:vipspacss
使用方法很是的簡單:html
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 上有詳細的使用介紹,在此再也不贅述。java
下面咱們研究下源碼。git
vipspa.jsgithub
首先看下基本的代碼結構:web
1 (function() { 2 // 構造函數 3 function Vipspa(){ 4 5 }; 6 7 //中間部分 8 Vipspa.prototyp = { 9 //.... 10 }; 11 12 window.vipspa = new Vipspa(); // 固然這塊能夠提取出來 13 }();//這塊也能夠作繼續的改進
這是一個簡單的模型模式。其中運用了匿名閉包,咱們將簡單的建立匿名函數,並當即執行。全部函數內部代碼都在閉包內。它提供了整個應用生命週期的私有和狀態。ajax
若是咱們想進一步擴展的話,能夠把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中得跨域。
好了,這個微框架先介紹到這裏,歡迎你們指正和吐槽。