JavaScript插件化开发方式
来源:才华咖 本文已影响3.04W人
来源:才华咖 本文已影响3.04W人
一,开篇分析
今天这篇文章我们说点什么那?嘿嘿嘿。我们接着上篇文章对不足的地方进行重构,以深入浅出的方式来逐步分析,让大家有一个循序渐进提高的过程。废话少说,进入正题。让我们先来回顾一下之前的
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多选模式,现在只是默认下拉模式。
看我本文,是不是要比上一篇代码优秀了很多呢,小伙伴们自己做项目也应该多想多做,尽量使自己的代码更加的合理。
javascript工厂方式的使用
JavaScript日期时间格式化函数
如何在Javascript中为String对象添加trim,ltrim,rtrim方法
java与JavaScript语言有何不同
JavaScript与java语言有何区别
使用ajax操作JavaScript对象的方法
javaScript工厂方式原始的方式
在Java中执行JavaScript代码
关于 response方法的javascript asp教程第六课
javascript的六种继承方式
javascript中String对象的slice()方法
JavaScript监听textarea中按键事件
网页开发中JavaScript传递参数方法比较
JavaScript与java语言的区别
JavaScript与java语言有何不同
JavaScript在Android的WebView中parseInt函数转换不正确
2017最新javascript中AJAX用法
关于javascript中apply()和call()方法的区别
常用的JavaScript模式
Javascript基础教程之数组array
关于JavaScript中的parse()的使用方法
Java中基于Aspectwerkz的AOP开发
javascript写的异步加载js文件函数
javascript中setInterval的用法总结
javascript正则表达式
aircy,的过程,作者,3页,教程,js,javascript,分享
PHPCms内容页支持JavaScript的修改方法
javascript函数命名的三种方式及区别
JavaScript中创建字典对象(dictionary)的实例
javascript显式类型转换的方法分析
关于异步JavaScript编程中的Promise使用方法
JavaScript中的函数式编程
Dreamweaver中JavaScript行为操作使用方法
必修一方程式化学课件
JavaScript插件化开发方式
嵌入式软件开发
javascript的方法
文化节开幕式发言稿
JavaScript 函数表达式
有关JavaScript中的prototype.bind()方法介绍