大熊君JavaScript插件化開發------(第二季)

一,開篇分析html

Hi,你們好!大熊君又和你們見面了,還記得昨天的那篇文章嗎------這個系列的開篇(第一季)。主要講述了以「jQuery的方式如何開發插件」,json

那麼今天咱們帶着昨天的疑問來繼續咱們的插件開發之旅。昨天的問題以下:閉包

(1),若是項目技術選型換了這些插件又是強依賴「jQuery」機制,咱們之前寫的插件將會不能用(假設不用jQuery的狀況),如何作重構那?異步

(2),重構插件的關鍵邏輯,咱們將如何組織那?ide

好了,帶着問題去學習今天的文章吧。函數

首先我不是否認「jQuery插件的方式」,其次是咱們要從不一樣的角度分析問題,好比說「jQuery插件有以下優勢」:學習

(1),把所有代碼放在閉包(一個即時執行函數)裏此時閉包至關於一個私有做用域,外部沒法訪問到內部的信息,而且不會存在全局變量的污染狀況。測試

(2),a) 避免全局依賴;b) 避免第三方破壞;c) 兼容jQuery操做符'$'和'jQuery '。this

那咱們重構將以什麼方式組織代碼那,是面向對象的思想(OOP)那?仍是過程化的思路進行到底那?仍是二者結合設計那?哈哈哈,繼續看。。。。。。url

 

二,重構昨天的例子

如下是昨天的Js部分源碼部分: 

 1 (function($){
 2     $.fn.bigbear = function(opts){
 3         opts = $.extend({},$.fn.bigbear.defaults,opts) ;
 4         return this.each(function(){
 5             var elem = $(this) ;
 6             elem.find("span").text(opts["title"]) ;
 7             $.get(opts["url"],function(data){
 8                 elem.find("div").text(data["text"]) ;
 9             }) ;
10         }) ;
11     } ;
12     $.fn.bigbear.defaults = {
13         title : "這是一個簡單的測試" ,
14         url : "data.json"
15     } ;
16 })(jQuery) ;

 咱們來逐行分析一下:

  首先肯定一下這個插件的功能

  (1),顯示咱們設置的標題文字信息。

  (2),動態經過異步的方式獲取內容信息。

好了!需求明確就好展開討論了,從上面的代碼不難看出邏輯組織很鬆散,過程化的思惟很明顯,因此第一步就是把咱們的功能需求

以類的方式有效地組織起來。看以下重構後的代碼:

  

 1 $(function(){
 2     $("#bb").bigbear() ;
 3 }) ;
 4 (function($){
 5     $.fn.bigbear = function(opts){
 6         opts = $.extend({},$.fn.bigbear.defaults,opts) ;
 7         return this.each(function(){
 8             var elem = $(this) ;
 9             var bb = new BigBear(elem,opts) ;
10             bb.getElem().trigger("data") ;
11         }) ;
12     } ;
13     $.fn.bigbear.defaults = {
14         title : "這是一個簡單的測試" ,
15         url : "data.json"
16     } ;
17 })(jQuery) ;
18 
19 function BigBear(elem,opts){
20     this.elem = elem ;
21     this.opts = opts ;
22     this.init() ;
23 } ;
24 var bbProto = BigBear.prototype ;
25 bbProto.getElem = function(){
26     return this.elem ;
27 } ;
28 bbProto.getOpts = function(){
29     return this.opts ;
30 } ;
31 bbProto.init = function(){
32     var that = this ;
33     this.getElem().on("data",function(){
34         that._setTitle(that.getOpts()["title"]) ;
35         $.get(that.getOpts()["url"],function(result){
36             that.getElem().find("div").text(result["text"]) ;
37         }) ;
38     }) ;
39 } ;
40 bbProto._setTitle = function(text){
41     this.getElem().find("span").text(text) ;
42 } ;

  哈哈哈,是否是代碼多了很多,其實這種方式就是面向對象的角度看問題,先去分析功能需求,而後設計咱們的類,雖說咱們不可能一下設計得很出色,

可是看問題角度改變了,咱們的代碼可讀性強了,以及更好地進行維護這樣咱們的目的也就達到了。

  如下是是摘自「Bootstrap」Js部分的相關源碼實現,以下圖:

  

 

不難看出也是類似的實現方式,經過類來維護咱們插件的主要邏輯。

 

(三),增長新功能,引出額外的類

  如今需求增長了,須要在體驗上有所變化,加載數據時有「loading」效果。

  實現思路能夠這樣,在原始的內容區把文字設置成「裝載數據中。。。。」的字樣,而後引入一個新的類,以下:

  

1 function Overlay(){
2 
3 } ;
4 var olProto = Overlay.prototype ;
5 olProto.show = function(){} ;
6 olProto.hide = function(){} ;
7 // 具體實現就不寫了

 

  好了,遮罩層已經有了,如今咱們怎麼集成進來那?咱們用組合的方式接入進來,以下:

 

 1 function BigBear(elem,opts){
 2     this.elem = elem ;
 3     this.opts = opts ;
 4     this.overlay = new Overlay() ;
 5     this.init() ;
 6 } ;
 7 var bbProto = BigBear.prototype ;
 8 bbProto.getElem = function(){
 9     return this.elem ;
10 } ;
11 bbProto.getOpts = function(){
12     return this.opts ;
13 } ;
14 bbProto.init = function(){
15     var that = this ;
16     var loadingText = "數據裝載中。。。" ;
17     this.getElem().on("data",function(){
18         that._setTitle(that.getOpts()["title"]) ;
19         that.overlay.show() ;
20         that.getElem().find("div").text(loadingText) ;
21         $.get(that.getOpts()["url"],function(result){
22             that.overlay.hide() ;
23             that.getElem().find("div").text(result["text"]) ;
24         }) ;
25     }) ;
26 } ;
27 bbProto._setTitle = function(text){
28     this.getElem().find("span").text(text) ;
29 } ;

 

  到此只爲咱們的功能就算是結束了,這樣寫的插件,我相信比第一個版本好不少,固然這不是最優的實現,須要從細節上不斷重構,可是這種方式是一種可選的開發插件的方式。

 

  如下是完整的代碼

  

 1 $(function(){
 2     $("#bb").bigbear() ;
 3 }) ;
 4 (function($){
 5     $.fn.bigbear = function(opts){
 6         opts = $.extend({},$.fn.bigbear.defaults,opts) ;
 7         return this.each(function(){
 8             var elem = $(this) ;
 9             var bb = new BigBear(elem,opts) ;
10             bb.getElem().trigger("data") ;
11         }) ;
12     } ;
13     $.fn.bigbear.defaults = {
14         title : "這是一個簡單的測試" ,
15         url : "data.json"
16     } ;
17 })(jQuery) ;
18 
19 function BigBear(elem,opts){
20     this.elem = elem ;
21     this.opts = opts ;
22     this.overlay = new Overlay() ;
23     this.init() ;
24 } ;
25 var bbProto = BigBear.prototype ;
26 bbProto.getElem = function(){
27     return this.elem ;
28 } ;
29 bbProto.getOpts = function(){
30     return this.opts ;
31 } ;
32 bbProto.init = function(){
33     var that = this ;
34     var loadingText = "數據裝載中。。。" ;
35     this.getElem().on("data",function(){
36         that._setTitle(that.getOpts()["title"]) ;
37         that.overlay.show() ;
38         that.getElem().find("div").text(loadingText) ;
39         $.get(that.getOpts()["url"],function(result){
40             that.overlay.hide() ;
41             that.getElem().find("div").text(result["text"]) ;
42         }) ;
43     }) ;
44 } ;
45 bbProto._setTitle = function(text){
46     this.getElem().find("span").text(text) ;
47 } ;
48 
49 function Overlay(){
50 
51 } ;
52 var olProto = Overlay.prototype ;
53 olProto.show = function(){} ;
54 olProto.hide = function(){} ;
55 // 具體實現就不寫了

 

 

(四),最後總結

  (1),面向對象的思考方式合理分析功能需求。

  (2),以類的方式來組織咱們的插件邏輯。

  (3),不斷重構上面的實例,最好本身寫一下,而且完善「Overlay」的邏輯。

  (4),你們學習完繼續思考一下,如何進行合理的重構那?不要設計過分,要遊刃有餘,推薦的方式是過程化設計與面向對象思想設計相結合。

 

 

 

                   哈哈哈,本篇結束,未完待續,但願和你們多多交流夠溝通,共同進步。。。。。。呼呼呼……(*^__^*)                      

相關文章
相關標籤/搜索