<dfn id="w48us"></dfn><ul id="w48us"></ul>
  • <ul id="w48us"></ul>
  • <del id="w48us"></del>
    <ul id="w48us"></ul>
  • JavaScript插件化開發方式

    時間:2024-10-08 16:33:11 JavaScript 我要投稿
    • 相關推薦

    JavaScript插件化開發方式

      一,開篇分析

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

      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 ; // 數據游標

      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)------非可操作狀態

      b)------可操作狀態

     。ǘ,打開思路,進行重構

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

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

      (2),職責劃分不清晰

     。3),流程梳理不健全

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

      (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 ; // 數據游標

      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._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")) ;

      } ;

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

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

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

      所以我們重構的目的很明確了,對!就是進行功能點的抽象,友好的職責劃分,那么我們如何實現那?

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

      復制代碼 代碼如下:

      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 !

      } ;

      第三步,建立數據操作接口:

      復制代碼 代碼如下:

      ISProto._setCurrent = function(){

      // put you code here !

      } ;

      ISProto._getCurrent = function(){

      // put you code here !

      } ;

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

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

      復制代碼 代碼如下:

      function ItemSelector(elem,opts){

      this.elem = elem ;

      this.opts = opts ;

      this.current = -1 ; // 數據游標

      } ;

      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")) ;

      } ;

      (四),最后總結

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

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

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

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

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

    【JavaScript插件化開發方式】相關文章:

    JavaScript日期時間格式化函數08-29

    對javascript的理解08-08

    常用的JavaScript模式09-22

    Javascript的this用法簡述08-15

    JavaScript學習筆記08-24

    JavaScript 基礎教學09-29

    JavaScript的課堂講解09-03

    AE影視常用插件FORM的應用技巧09-03

    JavaScript常用方法匯總10-25

    JavaScript數組常用方法介紹09-04

    主站蜘蛛池模板: 少妇人妻偷人精品视频| 一本一道精品欧美中文字幕| 久久精品二区| 91精品美女在线| 亚洲精品在线视频| 91人妻人人澡人人爽人人精品| 人人妻人人澡人人爽人人精品电影| 国产伦精品一区二区三区视频金莲 | 国产欧美日韩精品丝袜高跟鞋 | 国产成人高清精品一区二区三区 | 99RE8这里有精品热视频| 人妻AV一区二区三区精品| 精品午夜福利1000在线观看| 亚洲国产综合91精品麻豆| 99久久er这里只有精品18| 青青青国产精品一区二区| 亚洲国产精品丝袜在线观看| 国产精品麻豆入口| 亚洲精品无码专区2| 69久久夜色精品国产69| 亚洲AV成人精品网站在线播放| 精品熟女少妇aⅴ免费久久| 成人免费精品网站在线观看影片| 99久久精品国产高清一区二区| 亚洲精品国偷自产在线| 亚洲精品成人在线| 久久精品国产一区二区三区| 国产亚洲精品a在线观看| 国产国拍亚洲精品福利| 亚洲午夜精品久久久久久人妖| 久久九九青青国产精品| 97精品久久天干天天天按摩| 国产中老年妇女精品| 国产精品无码A∨精品影院| 久久久久人妻精品一区二区三区 | 国产精品福利区一区二区三区四区| 91精品国产福利在线导航| 国产三级精品三级在线专区1| 国产伦精品免编号公布| 国产国产精品人在线视| 国产精品ⅴ无码大片在线看|