欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript插件化開發(fā)教程(六)

 更新時間:2015年02月01日 09:39:00   投稿:hebedich  
本文是javascript插件化開發(fā)系列教程的第六篇文章,還是重點對上一篇文章不足的地方進行改進重構,逐步分析讓大家能有一個新的認識,希望小伙伴們能夠喜歡。

一,開篇分析

今天這篇文章我們說點什么那?嘿嘿嘿。我們接著上篇文章對不足的地方進行重構,以深入淺出的方式來逐步分析,讓大家有一個循序漸進提高的過程。廢話少說,進入正題。讓我們先來回顧一下之前的

Js部分的代碼,如下:

復制代碼 代碼如下:

 function ItemSelector(elem,opts){
     this.elem = elem ;
     this.opts = opts ;
 } ;
 var ISProto = ItemSelector.prototype ;
 ISProto.getElem = function(){
     return this.elem ;
 } ;
 ISProto.getOpts = function(){
     return this.opts ;
 } ;
 /* data manip*/
 ISProto._setCurrent = function(current){
     this.getOpts()["current"] = current ;
 } ;
 ISProto.getCurrentValue = function(current){
     return this.getOpts()["current"] ;
 } ;
 /* data manip*/
 ISProto.init = function(){
     var that = this ;
     this.getOpts()["current"] = null ; // 數(shù)據(jù)游標
     this._setItemValue(this.getOpts()["currentText"]) ;
     var itemsElem = that.getElem().find(".content .items") ;
     this.getElem().find(".title div").on("click",function(){
         itemsElem.toggle() ;
     }) ;
     this.getElem().find(".title span").on("click",function(){
         itemsElem.toggle() ;
     }) ;
     $.each(this.getOpts()["items"],function(i,item){
         item["id"] = (new Date().getTime()).toString() ;
         that._render(item) ;
     }) ;
 } ;
 ISProto._setItemValue = function(value){
     this.getElem().find(".title div").text(value)
 } ;
 ISProto._render = function(item){
     var that = this ;
     var itemElem = $("<div></div>")
     .text(item["text"])
     .attr("id",item["id"]) ;
     if("0" == item["disabled"]){
         itemElem.on("click",function(){
             var onChange = that.getOpts()["change"] ;
             that.getElem().find(".content .items").hide() ;
             that._setItemValue(item["text"]) ;
             that._setCurrent(item) ;
             onChange && onChange(item) ;
         })
         .mouseover(function(){
             $(this).addClass("item-hover") ;
         })
         .mouseout(function(){
             $(this).removeClass("item-hover") ;
         }) ;
     }
     else{
         itemElem.css("color","#ccc").on("click",function(){
             that.getElem().find(".content .items").hide() ;
             that._setItemValue(item["text"]) ;
         }) ;
     }
     itemElem.appendTo(this.getElem().find(".content .items")) ;
 } ;

  效果如下圖所示:

  a)------非可操作狀態(tài)

  b)------可操作狀態(tài)

(二),打開思路,進行重構

  大家從代碼不難看出,已經(jīng)通過“Js”中的語法特性,以面向對象的方式進行了有效的組織,比松散的過程化形式的組織方式好多了,但是仍然會發(fā)現(xiàn)有很多不足的地方。

  (1),里面重復代碼太多

 ?。?),職責劃分不清晰

 ?。?),流程梳理不健全

  我們基于以上幾點進行有效的重構,我們首先要梳理一下這個組件的需求,功能點如下:

 ?。?),初始化配置組件

復制代碼 代碼如下:

 $(function(){
     var itemSelector = new ItemSelector($("#item-selector"),{
         currentText : "Please Choose Item" ,
         items : [
             {
                 text : "JavaScript" ,
                 value : "js" ,
                 disabled : "1"
             } ,
             {
                 text : "Css" ,
                 value : "css" ,
                 disabled : "0"
             } ,
             {
                 text : "Html" ,
                 value : "html" ,
                 disabled : "0"
             }
         ] ,
     }) ;
     itemSelector.init() ;
 }) ;

  這塊代碼很清晰,不需要做任何修改,但是大家可以基于以上配置擴展功能,比如增加配置項“mode”支持多種選項方式。如:“checkbox勾選模式”。

  接下來是要完成初始化邏輯,如下:

復制代碼 代碼如下:

 ISProto.init = function(){
     var that = this ;
     this.getOpts()["current"] = null ; // 數(shù)據(jù)游標
     this._setItemValue(this.getOpts()["currentText"]) ;
     var itemsElem = that.getElem().find(".content .items") ;
     this.getElem().find(".title div").on("click",function(){
         itemsElem.toggle() ;
     }) ;
     this.getElem().find(".title span").on("click",function(){
         itemsElem.toggle() ;
     }) ;
     $.each(this.getOpts()["items"],function(i,item){
         item["id"] = (new Date().getTime()).toString() ;
         that._render(item) ;
     }) ;
 } ;

  這段代碼問題很多,職責不明確,初始化邏輯包含了功能點的細節(jié)實現(xiàn)。

  再繼續(xù)看渲染部分代碼:

復制代碼 代碼如下:

 ISProto._render = function(item){
     var that = this ;
     var itemElem = $("<div></div>")
     .text(item["text"])
     .attr("id",item["id"]) ;
     if("0" == item["disabled"]){
         itemElem.on("click",function(){
             var onChange = that.getOpts()["change"] ;
             that.getElem().find(".content .items").hide() ;
             that._setItemValue(item["text"]) ;
             that._setCurrent(item) ;
             onChange && onChange(item) ;
         })
         .mouseover(function(){
             $(this).addClass("item-hover") ;
         })
         .mouseout(function(){
             $(this).removeClass("item-hover") ;
         }) ;
     }
     else{
         itemElem.css("color","#ccc").on("click",function(){
             that.getElem().find(".content .items").hide() ;
             that._setItemValue(item["text"]) ;
         }) ;
     }
     itemElem.appendTo(this.getElem().find(".content .items")) ;
 } ;

  問題很明顯,發(fā)現(xiàn)了重復性的操作,應該進行合理的抽象,已達到復用的目的。

  整個組建的流程包括初始化,渲染(事件綁定),還有就是相關的數(shù)據(jù)操作方法以及dom操作的輔助方法。

  綜上所述,經(jīng)過簡單的梳理后,我們應該建立起功能的操作目的以及流程主線的任務分配,各負其責。

  所以我們重構的目的很明確了,對!就是進行功能點的抽象,友好的職責劃分,那么我們?nèi)绾螌崿F(xiàn)那?

  第一步,建立流程功能方法:(方法接口)

復制代碼 代碼如下:

ISProto.init = function(){
   // put you code here !
} ;
ISProto._render = function(){
   // put you code here !
} ;

 第二部,建立抽象后的方法接口:

復制代碼 代碼如下:

ISProto._fnItemSelectorDelegateHandler = function(){
   // put you code here !
} ;
ISProto._fnTriggerHandler = function(){
   // put you code here !
} ;
ISProto._addOrRemoveClass = function(){
   // put you code here !
} ;

第三步,建立數(shù)據(jù)操作接口:

復制代碼 代碼如下:

 ISProto._setCurrent = function(){
    // put you code here !
 } ;
 ISProto._getCurrent = function(){
    // put you code here !
 } ;

  還有一些參照下面的完整源碼,這里只是說的思路。

(三),完整代碼以供學習,本代碼已經(jīng)過測試

復制代碼 代碼如下:

function ItemSelector(elem,opts){
    this.elem = elem ;
    this.opts = opts ;
    this.current = -1 ; // 數(shù)據(jù)游標
} ;
var ISProto = ItemSelector.prototype ;
/* getter api*/
ISProto.getElem = function(){
    return this.elem ;
} ;
ISProto.getOpts = function(){
    return this.opts ;
} ;
ISProto._getCurrent = function(){
    return this.current ;
} ;
/* getter api*/
/* data manip*/
ISProto._setCurrent = function(current){
    this.current = current ;
} ;
ISProto._setItemText = function(text){
    this.getElem().find(".title div").text(text) ;
} ;
/* data manip*/
 
/* update on 2015 1/31 23:38 */
ISProto._fnTriggerHandler = function(index,text,value){
    if(this._isDisabled(value)){
        index = -1 ;
        text = this.getOpts()["currentText"] ;
    }
    this._setItemText(text) ;
    this._setCurrent(index) ;
    this.getElem().find(".content .items").hide() ;
} ;
ISProto._addOrRemoveClass = function(elem,className,addIs){
    if(addIs){
        elem.addClass(className) ;
    }
    else{
        elem.removeClass(className) ;
    }
} ;
ISProto._fnItemSelectorDelegateHandler = function(){
    var that = this ;
    this.getElem().on("click","[data-toggle]",function(){
        that.getElem().find(".content .items").toggle() ;
    }) ;
} ;
ISProto._isDisabled = function(value){
    return ("1" == value) ? true : false ;
} ;
/* update on 2015 1/31 23:38 */
ISProto.init = function(){
    var that = this ;
    this._fnItemSelectorDelegateHandler() ;
    $.each(this.getOpts()["items"],function(i,item){
        item["index"] = i ;
        that._render(item) ;
    }) ;
    this._fnTriggerHandler(this._getCurrent(),this.getOpts()["currentText"],"1") ;
} ;
ISProto._render = function(item){
    var that = this ;
    var itemElem = $("<div></div>").text(item["text"]).attr("id",item["index"]) ;
    var activeClass = ("0" == item["disabled"]) ? "item-hover" : "item-disabled-hover" ;
    itemElem.on("click",function(){
        that._fnTriggerHandler(item["index"],item["text"],item["disabled"]) ;
    })
    .mouseover(function(){
        that._addOrRemoveClass($(this),activeClass,true) ;
    })
    .mouseout(function(){
        that._addOrRemoveClass($(this),activeClass,false) ;
    }) ;
    itemElem.appendTo(this.getElem().find(".content .items")) ;
} ;
  

(四),最后總結

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

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

 ?。?),不斷重構上面的實例,如何進行合理的重構那?不要設計過度,要游刃有余,推薦的方式是過程化設計與面向對象思想設計相結合。

    (4),下篇文章中會擴展相關功能,比如“mode”這個屬性,為"1"時支持checkbox多選模式,現(xiàn)在只是默認下拉模式。

看我本文,是不是要比上一篇代碼優(yōu)秀了很多呢,小伙伴們自己做項目也應該多想多做,盡量使自己的代碼更加的合理。

相關文章

  • 67 個節(jié)約開發(fā)時間的前端開發(fā)者的工具、庫和資源

    67 個節(jié)約開發(fā)時間的前端開發(fā)者的工具、庫和資源

    在本文中,我不會去談 React、Angular、Vue 等等這些大的前端框架,也不會談 Atom、VS code、Sublime 等等這些已經(jīng)很出名的代碼編輯器,我只是想簡單的分享一套我認為有助于提升開發(fā)者工作流的工具集
    2017-09-09
  • 微信小程序實現(xiàn)點擊生成隨機驗證碼

    微信小程序實現(xiàn)點擊生成隨機驗證碼

    這篇文章主要為大家詳細介紹了微信小程序實現(xiàn)點擊生成隨機驗證碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • 淺談JavaScript中運算符的優(yōu)先級

    淺談JavaScript中運算符的優(yōu)先級

    這篇文章主要給大家簡單介紹了JavaScript中運算符的優(yōu)先級的相關問題,十分的實用,有需要的小伙伴可以參考下。
    2015-07-07
  • JavaScript中的常見錯誤與異常處理分析

    JavaScript中的常見錯誤與異常處理分析

    這篇文章主要為大家信息介紹了JavaScript中的常見錯誤與異常處理的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • javascript 在firebug調(diào)試時用console.log的方法

    javascript 在firebug調(diào)試時用console.log的方法

    當你使用console.log()函數(shù)時,下面的firebug一定要打開,不然這函數(shù)在用firefox運行時無效且影響正常程序,如果用IE打開,將會出錯
    2012-05-05
  • 一文了解ES5和ES6的區(qū)別

    一文了解ES5和ES6的區(qū)別

    ES6是JavaScript語言的主要增強,允許我們編寫程序,ES6適用于復雜的應用程序,盡管ES5和ES6在本質上有一些相似之處,但它們之間也有許多不同之處,下面這篇文章主要給大家介紹了關于ES5和ES6區(qū)別的相關資料,需要的朋友可以參考下
    2023-05-05
  • 詳解JavaScript的內(nèi)存空間、賦值和深淺拷貝

    詳解JavaScript的內(nèi)存空間、賦值和深淺拷貝

    這篇文章主要介紹了JavaScript的內(nèi)存空間、賦值和深淺拷貝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • JS SetInterval 代碼實現(xiàn)頁面輪詢

    JS SetInterval 代碼實現(xiàn)頁面輪詢

    setInterval 是一個實現(xiàn)定時調(diào)用的函數(shù),可按照指定的周期(以毫秒計)來調(diào)用函數(shù)或計算表達式。下面通過本文給大家分享JS SetInterval 代碼實現(xiàn)頁面輪詢,感興趣的朋友一起看看吧
    2017-08-08
  • javascript自動生成包含數(shù)字與字符的隨機字符串

    javascript自動生成包含數(shù)字與字符的隨機字符串

    這篇文章主要介紹了javascript自動生成包含數(shù)字與字符的隨機字符串,涉及Math.random()和Math.floor()兩個函數(shù)的使用技巧,需要的朋友可以參考下
    2015-02-02
  • js仿蘋果iwatch外觀的計時器代碼分享

    js仿蘋果iwatch外觀的計時器代碼分享

    這篇文章主要介紹了JS+CSS3實現(xiàn)的類似于蘋果iwatch計時器特效,很實用的代碼,推薦給大家,有需要的小伙伴可以參考下。
    2015-08-08

最新評論