• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. JavaScript插件化開發(fā)方式

        時(shí)間:2024-10-08 16:33:11 JavaScript 我要投稿
        • 相關(guān)推薦

        JavaScript插件化開發(fā)方式

          一,開篇分析

          今天這篇文章我們說點(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 = $("

        ")

          .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”中的語(yǔ)法特性,以面向?qū)ο蟮姆绞竭M(jìn)行了有效的組織,比松散的過程化形式的組織方式好多了,但是仍然會(huì)發(fā)現(xiàn)有很多不足的地方。

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

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

          (3),流程梳理不健全

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

          (1),初始化配置組件

          復(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 = $("

        ")

          .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*/

          /* 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 ;

          } ;

          /* 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 = $("

        ").text(item["text"]).attr("id",item["index"]) ;

          var activeClass = ("0" == item["disabled"]) " : "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é)

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

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

          (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)該多想多做,盡量使自己的代碼更加的合理。

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

        【JavaScript插件化開發(fā)方式】相關(guān)文章:

        JavaScript日期時(shí)間格式化函數(shù)08-29

        對(duì)javascript的理解08-08

        常用的JavaScript模式09-22

        Javascript的this用法簡(jiǎn)述08-15

        JavaScript學(xué)習(xí)筆記08-24

        JavaScript 基礎(chǔ)教學(xué)09-29

        JavaScript的課堂講解09-03

        AE影視常用插件FORM的應(yīng)用技巧09-03

        JavaScript常用方法匯總10-25

        JavaScript數(shù)組常用方法介紹09-04

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 亚洲老妇在线观看 | 亚洲狠狠丁香婷婷综合久久久 | 一本大道香蕉久在线播放29 | 亚洲大香伊蕉在人线国产 | 亚洲成年网站青青草原 | 伊人久久大香线焦亚洲日本 |

            JavaScript插件化開發(fā)方式

              一,開篇分析

              今天這篇文章我們說點(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 = $("

            ")

              .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”中的語(yǔ)法特性,以面向?qū)ο蟮姆绞竭M(jìn)行了有效的組織,比松散的過程化形式的組織方式好多了,但是仍然會(huì)發(fā)現(xiàn)有很多不足的地方。

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

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

              (3),流程梳理不健全

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

              (1),初始化配置組件

              復(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 = $("

            ")

              .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*/

              /* 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 ;

              } ;

              /* 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 = $("

            ").text(item["text"]).attr("id",item["index"]) ;

              var activeClass = ("0" == item["disabled"]) " : "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é)

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

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

              (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)該多想多做,盡量使自己的代碼更加的合理。