JavaScript插件化開發方式
一,開篇分析
今天這篇文章我們説點什麼那?嘿嘿嘿。我們接着上篇文章對不足的地方進行重構,以深入淺出的方式來逐步分析,讓大家有一個循序漸進提高的過程。廢話少説,進入正題。讓我們先來回顧一下之前的
Js部分的代碼,如下:
複製代碼 代碼如下:
function ItemSelector(elem,opts){
= elem ;
= opts ;
} ;
var ISProto = otype ;
lem = function(){
return ;
} ;
pts = function(){
return ;
} ;
/* data manip*/
ISProto._setCurrent = function(current){
pts()["current"] = current ;
} ;
urrentValue = function(current){
return pts()["current"] ;
} ;
/* data manip*/
= function(){
var that = this ;
pts()["current"] = null ; // 數據遊標
this._setItemValue(pts()["currentText"]) ;
var itemsElem = lem()("ent s") ;
lem()("e div")("click",function(){
le() ;
}) ;
lem()("e span")("click",function(){
le() ;
}) ;
$(pts()["items"],function(i,item){
item["id"] = (new Date()ime())ring() ;
that._render(item) ;
}) ;
} ;
ISProto._setItemValue = function(value){
lem()("e div")(value)
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
(item["text"])
("id",item["id"]) ;
if("0" == item["disabled"]){
("click",function(){
var onChange = pts()["change"] ;
lem()("ent s")() ;
that._setItemValue(item["text"]) ;
that._setCurrent(item) ;
onChange && onChange(item) ;
})
eover(function(){
$(this)lass("item-hover") ;
})
eout(function(){
$(this)veClass("item-hover") ;
}) ;
}
else{
("color","#ccc")("click",function(){
lem()("ent s")() ;
that._setItemValue(item["text"]) ;
}) ;
}
ndTo(lem()("ent s")) ;
} ;
效果如下圖所示:
a)------非可操作狀態
b)------可操作狀態
(二),打開思路,進行重構
大家從代碼不難看出,已經通過“Js”中的語法特性,以面向對象的方式進行了有效的組織,比鬆散的過程化形式的組織方式好多了,但是仍然會發現有很多不足的地方。
(1),裏面重複代碼太多
(2),職責劃分不清晰
我們基於以上幾點進行有效的重構,我們首先要梳理一下這個組件的需求,功能點如下:
(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"
}
] ,
}) ;
() ;
}) ;
這塊代碼很清晰,不需要做任何修改,但是大家可以基於以上配置擴展功能,比如增加配置項“mode”支持多種選項方式。如:“checkbox勾選模式”。
接下來是要完成初始化邏輯,如下:
複製代碼 代碼如下:
= function(){
var that = this ;
pts()["current"] = null ; // 數據遊標
this._setItemValue(pts()["currentText"]) ;
var itemsElem = lem()("ent s") ;
lem()("e div")("click",function(){
le() ;
}) ;
lem()("e span")("click",function(){
le() ;
}) ;
$(pts()["items"],function(i,item){
item["id"] = (new Date()ime())ring() ;
that._render(item) ;
}) ;
} ;
這段代碼問題很多,職責不明確,初始化邏輯包含了功能點的細節實現。
再繼續看渲染部分代碼:
複製代碼 代碼如下:
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")
(item["text"])
("id",item["id"]) ;
if("0" == item["disabled"]){
("click",function(){
var onChange = pts()["change"] ;
lem()("ent s")() ;
that._setItemValue(item["text"]) ;
that._setCurrent(item) ;
onChange && onChange(item) ;
})
eover(function(){
$(this)lass("item-hover") ;
})
eout(function(){
$(this)veClass("item-hover") ;
}) ;
}
else{
("color","#ccc")("click",function(){
lem()("ent s")() ;
that._setItemValue(item["text"]) ;
}) ;
}
ndTo(lem()("ent s")) ;
} ;
問題很明顯,發現了重複性的操作,應該進行合理的'抽象,已達到複用的目的。
整個組建的流程包括初始化,渲染(事件綁定),還有就是相關的數據操作方法以及dom操作的輔助方法。
綜上所述,經過簡單的梳理後,我們應該建立起功能的操作目的以及流程主線的任務分配,各負其責。
所以我們重構的目的很明確了,對!就是進行功能點的抽象,友好的職責劃分,那麼我們如何實現那?
第一步,建立流程功能方法:(方法接口)
複製代碼 代碼如下:
= 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){
= elem ;
= opts ;
ent = -1 ; // 數據遊標
} ;
var ISProto = otype ;
/* getter api*/
lem = function(){
return ;
} ;
pts = function(){
return ;
} ;
ISProto._getCurrent = function(){
return ent ;
} ;
/* getter api*/
/* data manip*/
ISProto._setCurrent = function(current){
ent = current ;
} ;
ISProto._setItemText = function(text){
lem()("e div")(text) ;
} ;
/* data manip*/
/* on 2015 1/31 23:38 */
ISProto._fnTriggerHandler = function(index,text,value){
if(this._isDisabled(value)){
index = -1 ;
text = pts()["currentText"] ;
}
this._setItemText(text) ;
this._setCurrent(index) ;
lem()("ent s")() ;
} ;
ISProto._addOrRemoveClass = function(elem,className,addIs){
if(addIs){
lass(className) ;
}
else{
veClass(className) ;
}
} ;
ISProto._fnItemSelectorDelegateHandler = function(){
var that = this ;
lem()("click","[data-toggle]",function(){
lem()("ent s")le() ;
}) ;
} ;
ISProto._isDisabled = function(value){
return ("1" == value) ? true : false ;
} ;
/* on 2015 1/31 23:38 */
= function(){
var that = this ;
this._fnItemSelectorDelegateHandler() ;
$(pts()["items"],function(i,item){
item["index"] = i ;
that._render(item) ;
}) ;
this._fnTriggerHandler(this._getCurrent(),pts()["currentText"],"1") ;
} ;
ISProto._render = function(item){
var that = this ;
var itemElem = $("
")(item["text"])("id",item["index"]) ;
var activeClass = ("0" == item["disabled"]) " : "item-disabled-hover" ;
("click",function(){
that._fnTriggerHandler(item["index"],item["text"],item["disabled"]) ;
})
eover(function(){
that._addOrRemoveClass($(this),activeClass,true) ;
})
eout(function(){
that._addOrRemoveClass($(this),activeClass,false) ;
}) ;
ndTo(lem()("ent s")) ;
} ;
(四),最後總結
(1),面向對象的思考方式合理分析功能需求。
(2),以類的方式來組織我們的插件邏輯。
(3),不斷重構上面的實例,如何進行合理的重構那?不要設計過度,要遊刃有餘,推薦的方式是過程化設計與面向對象思想設計相結合。
(4),下篇文章中會擴展相關功能,比如“mode”這個屬性,為"1"時支持checkbox多選模式,現在只是默認下拉模式。
看我本文,是不是要比上一篇代碼優秀了很多呢,小夥伴們自己做項目也應該多想多做,儘量使自己的代碼更加的合理。
-
網頁設計黃金配色原則是什麼
身為網頁設計新手的你,是不是還在糾結於你製作的網頁找不到一組完美的配色方案?在本教程中我們將與你分享6條肯定會火,並且“錯不了”的指導方針,你可以按照這些原則把握最基本的色彩規律。現在我們分享的這些原則都不是規則,你會在你的職業生涯中創造出更多的配色...
-
javascript設置創建動態表格的方法
兩種JavaScript動態創建table表格的方法,分享給大家,具體實現如下方法一:最原始的方法,創建一一元素vara1=teElement("table");vara2=teElement("tbody");vara3=teElement("tr");vara4=teElement("td");//開始appendchild()追加各個元素ndChild(a4);ndChild(a3);nd...
-
JavaScript 小型打飛機遊戲實現和原理説明
JavaScript小型打飛機遊戲實現和原理説明玩法説明:上下左右控制移動,空格發彈。每打中一個敵機就加100分,每提升5000分,玩家的飛機的一次發彈數就加一,最多四,被敵機撞到或者讓敵機飛到底部就算輸。。。。演示代碼:http://demo./js/FlyBeat/遊戲目前的功能還是比較簡...
-
Dedecms中常用數據調用的sql語句
本文實例彙總了Dedecms中常用數據調用的'sql語句。分享給大家供大家參考。具體如下:{dede:sqlsql="selectcount(*)ascfromdede_archiveswherechannel=1"}共有文章:[field:c/]篇{/dede:sql}{dede:sqlsql="selectcount(*)ascfromdede_archiveswherechannel=2"}共...