狠狠操网,91中文字幕在线观看,精品久久香蕉国产线看观看亚洲,亚洲haose在线观看

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

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 p").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 p").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 p").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 p").text(text) ;

  } ;

  /* data manip*/

  /* on 2023 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 2023 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")) ;

  } ;

 。ㄋ模詈罂偨Y(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)該多想多做,盡量使自己的代碼更加的合理。

版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 yyfangchan@163.com (舉報(bào)時(shí)請(qǐng)帶上具體的網(wǎng)址) 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除