最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

一,開篇分析

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

Js部分的代碼,如下:

復(fù)制代碼 代碼如下:

 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ù)游標(biāo)
     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ìn)行重構(gòu)

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

 ?。?),里面重復(fù)代碼太多

 ?。?),職責(zé)劃分不清晰

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

  我們基于以上幾點(diǎn)進(jìn)行有效的重構(gòu),我們首先要梳理一下這個(gè)組件的需求,功能點(diǎn)如下:

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

復(fù)制代碼 代碼如下:

 $(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() ;
 }) ;

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

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

復(fù)制代碼 代碼如下:

 ISProto.init = function(){
     var that = this ;
     this.getOpts()["current"] = null ; // 數(shù)據(jù)游標(biāo)
     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) ;
     }) ;
 } ;

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

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

復(fù)制代碼 代碼如下:

 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)了重復(fù)性的操作,應(yīng)該進(jìn)行合理的抽象,已達(dá)到復(fù)用的目的。

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

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

  所以我們重構(gòu)的目的很明確了,對(duì)!就是進(jìn)行功能點(diǎn)的抽象,友好的職責(zé)劃分,那么我們?nèi)绾螌?shí)現(xiàn)那?

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

復(fù)制代碼 代碼如下:

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

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

復(fù)制代碼 代碼如下:

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

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

復(fù)制代碼 代碼如下:

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

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

(三),完整代碼以供學(xué)習(xí),本代碼已經(jīng)過測(cè)試

復(fù)制代碼 代碼如下:

function ItemSelector(elem,opts){
    this.elem = elem ;
    this.opts = opts ;
    this.current = -1 ; // 數(shù)據(jù)游標(biāo)
} ;
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")) ;
} ;
  

(四),最后總結(jié)

 ?。?),面向?qū)ο蟮乃伎挤绞胶侠矸治龉δ苄枨蟆?/p>

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

  (3),不斷重構(gòu)上面的實(shí)例,如何進(jìn)行合理的重構(gòu)那?不要設(shè)計(jì)過度,要游刃有余,推薦的方式是過程化設(shè)計(jì)與面向?qū)ο笏枷朐O(shè)計(jì)相結(jié)合。

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

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

相關(guān)文章

  • JavaScript cookie與session的使用及區(qū)別深入探究

    JavaScript cookie與session的使用及區(qū)別深入探究

    這篇文章主要介紹了Java中Cookie和Session詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-10-10
  • js實(shí)現(xiàn)簡(jiǎn)單的輪播圖效果

    js實(shí)現(xiàn)簡(jiǎn)單的輪播圖效果

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)簡(jiǎn)單的輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Iframe 自適應(yīng)高度并實(shí)時(shí)監(jiān)控高度變化的js代碼

    Iframe 自適應(yīng)高度并實(shí)時(shí)監(jiān)控高度變化的js代碼

    不得不用到iframe,且被強(qiáng)烈要求不能讓它出現(xiàn)滾動(dòng)條!嵌入的頁面肯定是高度不一的,頁面中也不能出現(xiàn)大片空白,所以也不能寫死高度!真是麻鬼煩??!
    2009-10-10
  • 詳解webpack 如何集成第三方j(luò)s庫(kù)

    詳解webpack 如何集成第三方j(luò)s庫(kù)

    這篇文章主要介紹了詳解webpack 如何集成第三方j(luò)s庫(kù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • js實(shí)現(xiàn)輪播圖自動(dòng)切換

    js實(shí)現(xiàn)輪播圖自動(dòng)切換

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)輪播圖自動(dòng)切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JavaScript原型繼承之基礎(chǔ)機(jī)制分析

    JavaScript原型繼承之基礎(chǔ)機(jī)制分析

    由于語言設(shè)計(jì)上的原因,JavaScript 沒有真正意義上“類”的概念。而通常使用的 new 命令實(shí)例化對(duì)象的方法,其實(shí)是對(duì)原型對(duì)象的實(shí)例化。
    2011-08-08
  • 詳解JavaScript正則表達(dá)式之RegExp對(duì)象

    詳解JavaScript正則表達(dá)式之RegExp對(duì)象

    這篇文章主要介紹了JavaScript正則表達(dá)式之RegExp對(duì)象,對(duì)RegExp對(duì)象的基本使用方法,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下
    2015-12-12
  • 前端監(jiān)控頁面異常的常用方法

    前端監(jiān)控頁面異常的常用方法

    前端開發(fā)常見問題之一: 資源異常、js異常,頁面出了問題常見的想法是:如何看到錯(cuò)誤信息,資源腳本是否正常,像js、css、圖片這些資源文件經(jīng)常受網(wǎng)絡(luò)等原因,導(dǎo)致資源加載異常,這些會(huì)直接影響我們的頁面,本文給大家介紹前端監(jiān)控頁面異常的常用方法,需要的朋友可以參考下
    2025-04-04
  • javascript圖像處理—邊緣梯度計(jì)算函數(shù)

    javascript圖像處理—邊緣梯度計(jì)算函數(shù)

    上一篇文章,我們講解了圖像處理中的膨脹和腐蝕函數(shù),這篇文章將做邊緣梯度計(jì)算函數(shù),感興趣的朋友可以了解下
    2013-01-01
  • 深入理解JavaScript系列(10) JavaScript核心(晉級(jí)高手必讀篇)

    深入理解JavaScript系列(10) JavaScript核心(晉級(jí)高手必讀篇)

    本篇是ECMA-262-3 in detail系列的一個(gè)概述(本人后續(xù)會(huì)翻譯整理這些文章到本系列(第11-19章)。每個(gè)章節(jié)都有一個(gè)更詳細(xì)的內(nèi)容鏈接,你可以繼續(xù)讀一下每個(gè)章節(jié)對(duì)應(yīng)的詳細(xì)內(nèi)容鏈接進(jìn)行更深入的了解
    2012-01-01

最新評(píng)論

和田市| 滦平县| 肇东市| 红原县| 新晃| 霸州市| 津南区| 丹寨县| 凤冈县| 江城| 丹寨县| 哈巴河县| 晋州市| 墨脱县| 盐亭县| 泰兴市| 谢通门县| 泸州市| 兰溪市| 县级市| 通州区| 大宁县| 汽车| 嘉荫县| 寿阳县| 西华县| 剑川县| 玛纳斯县| 嘉兴市| 吉林省| 渭南市| 峡江县| 牟定县| 澄城县| 敖汉旗| 阿坝县| 宽城| 怀安县| 岳池县| 荥阳市| 桦川县|