JavaScript插件化开发教程(六)
一,开篇分析
今天这篇文章我们说点什么那?嘿嘿嘿。我们接着上篇文章对不足的地方进行重构,以深入浅出的方式来逐步分析,让大家有一个循序渐进提高的过程。废话少说,进入正题。让我们先来回顾一下之前的
射流研究…部分的代码,如下:
复制代码代码如下:功能ItemElector(elem,opts){ this。elem=elemthis . opts=opts };var ISProto=项目选举人。原型;isproto。getelem=function(){返回这个。elem} ;互联网服务提供商协议。GetOpts=function(){返回这个。opts} ;/*数据manip*/ISProto ._ SetCurrent=function(current){ this。GetOpts()[' current ']=current;} ;isProto。GetCurrentValue=function(current){ return this。GetOpts()[' current '];} ;/* data manip */isproto。init=函数(){ var那=这是。GetOpts()[' current ']=null;//数据游标这个_ SetItemValue(这。GetOpts()[' CurrentText ']);var itemsElem=that.getElem().查找('。内容项目');this.getElem().查找('。标题div ').on('click '),function(){ item elem。toggle();}) ;this.getElem().查找('。标题跨度')。on('click ',function(){ item elem。toggle();}) ;$.每个(this.getOpts()['items'],函数(I,item){ item['id']=(新日期()。getTime()).toString();那个_render(项目);}) ;} ;互联网协议._setItemValue=函数(值){ this.getElem().查找('。标题div ').文本(值)};互联网协议._渲染=函数(项){ var=thisvar itemElem=$('div/div ').文本(项目['text']).attr('id ',项目[' id ']);if(' 0 '==item[' disabled ']){ item elem。on(' click '),function(){ var onChange=that。getopts()[' change '];that.getElem().查找('。内容。项目')。hide();那个_setItemValue(项[' text ']);那个_setCurrent(项目);onChange onChange(项目);}) .mouseover(函数(){ $(this)).add CLaSS(' item-hover ');}) .mouseout(函数(){ $(此)).移除CLaSS(' item-hover ');}) ;} else{ itemElem.css('color ',' #ccc ').on('click '),function(){ that.getElem().查找('。内容。项目')。hide();那个_setItemValue(项[' text ']);}) ;} ItemElem。附录(这个。GetElem().查找('。内容项目');} ;
效果如下图所示:
a) -非可操作状态
b) -可操作状态
(二),打开思路,进行重构
大家从代码不难看出,已经通过“Js”中的语法特性,以面向对象的方式进行了有效的组织,比松散的过程化形式的组织方式好多了,但是仍然会发现有很多不足的地方。
(1),里面重复代码太多
(2),职责划分不清晰
(3),流程梳理不健全
我们基于以上几点进行有效的重构,我们首先要梳理一下这个组件的需求,功能点如下:
(1),初始化配置组件
复制代码代码如下: $(function(){ var items elector=new items elector($(' # Item-selector '),{ currentText : '请选择项目,项目: [ { text : 'JavaScript ',值: 'js ',禁用: '1' },{ text : 'Css ',值: 'Css ',禁用: '0' },{ text : ' Html 'items elector。init();}) ;
这块代码很清晰,不需要做任何修改,但是大家可以基于以上配置扩展功能,比如增加配置项"模式"支持多种选项方式。如:"复选框勾选模式"。
接下来是要完成初始化逻辑,如下:
复制代码代码如下:是罗托。init=function(){ var=that this;这个。GetOpts()[' current ']=null;//数据游标这个_ SetItemValue(这。GetOpts()[' CurrentText ']);var itemsElem=that.getElem().查找('。内容项目');this.getElem().查找('。标题div ').on('click '),function(){ item elem。toggle();}) ;this.getElem().查找('。标题跨度')。on('click '),function(){ item elem。toggle();}) ;$.每个(this.getOpts()['items'],函数(I,item){ item['id']=(新日期()。getTime()).toString();那个_render(项目);}) ;} ;
这段代码问题多,职责不清,初始化逻辑包含了功能点的详细实现。
继续看代码:的渲染部分。
复制代码如下: isproto。_ render=函数(项){ var=this;var itemElem=$('div/div ')。文本(项目['text'])。attr('id ',项目[' id ']);if(' 0 '==item[' disabled ']){ itemelem . on(' click '),function(){ var onChange=that . getopts()[' change '];that.getElem()。查找('。内容。项目')。hide();那个。_setItemValue(项[' text ']);那个。_setCurrent(项目);onChange onChange(项目);}) .mouseover(function(){ $(this))。add CLaSS(' item-hover ');}) .mouseout(函数(){ $(this))。remove CLaSS(' item-hover ');}) ;} else{ itemElem.css('color ',' #ccc ')。on('click '),function(){ that.getElem()。查找('。内容。项目')。hide();那个。_setItemValue(项[' text ']);}) ;} ItemElem . appendto(this . GetElem()。查找('。内容。items’);} ;
问题很明显。重复的操作已经发现,应该合理抽象,从而达到复用的目的。
整个构建过程包括初始化和渲染(事件绑定),以及相关的数据操作方法和dom操作的辅助方法。
综上所述,简单梳理后,要确立职能的操作目的和流程主线的任务分配。
所以我们重建的目的很明确,对吧!是进行功能点的抽象和友好的职责划分,那么我们如何实现呢?
第一步是建立过程函数方法:(方法接口)。
复制的代码如下: is proto . init=function(){//把你的代码放在这里!} ;ISProto。_render=function(){ //把你的代码放在这里!} ;
第二,建立抽象的方法接口:
复制代码如下: isproto。_ fnitemselectdelegatehandler=function(){//把你的代码放在这里!} ;ISProto。_ fnTriggerHandler=function(){//把你的代码放在这里!} ;ISProto。_ AddRemoveClass=function(){//把你的代码放在这里!} ;
第三步,建立数据操作界面:
复制的代码如下: isproto。_ set current=function(){//把你的代码放在这里!} ;ISProto。_getCurrent=function(){ //把你的代码放在这里!} ;有些参考下面完整的源代码,但这里只是思路。
(3)、完整的学习代码,这个代码已经过测试。
复制代码代码如下:功能ItemElector(elem,opts){ this。elem=elemthis.opts=optsthis。电流=-1;//数据游标} ;var ISProto=项目选举人。原型;/* getter API */isproto。getelem=function(){返回这个。elem} ;互联网服务提供商协议。GetOpts=function(){返回这个。opts} ;互联网协议._ GetCurrent=function(){返回这个。电流;} ;/* getter API *//*数据manip */ISProto ._ SetCurrent=function(current){ this。电流=电流;} ;互联网协议._setItemText=函数(文本){ this.getElem().查找('。标题div ').文本(文本);} ;/*数据manip*//*更新于2015年一月31日23:38 */ISProto ._fnTriggerHandler=函数(索引、文本、值){如果(这._ Isdisabled(value)){ index=-1;文本=这个。getopts()[' CurrentText '];}这个_setItemText(文本);这个_setCurrent(索引);this.getElem().查找('。内容。项目')。hide();} ;互联网协议._ AddRemoveClass=function(elem,className,ADIses){ if(ADIses){ elem。AddClass(类名);} else { elem。移除类(CLaSS name);}} ;互联网协议._ fnitemselectdelegatehandler=function(){ var=证明这一点;this.getElem().on('click ','[data-toggle]',function(){ that.getElem().查找('。内容。项目')。toggle();}) ;} ;互联网协议._isDisabled=函数(值){ return ('1'==值)?真:假;} ;/*更新于2015年一月31日23:38 */isproto。init=函数(){ var那=这个这个. fnitemselectedelegatehandler();$.每个(this.getOpts()['items'],函数(I,item){ item[' index ']=I;那个_render(项目);}) ;这个_fnTriggerHandler(这. getCurrent(),this.getOpts()['currentText'],' 1 ');} ;互联网协议._渲染=函数(项){ var=thisvar itemElem=$('div/div ').文本(项目['text']).attr('id ',项[' index ']);var activeClass=('0'==项['禁用'])?项目-悬停' : '项目-禁用-悬停;itemElem.on('click ',function(){即._fnTriggerHandler(项['索引'],项['text'],项[' disabled ']);}) .鼠标悬停()函数(){即_ AddRemoveClass($(this),activeClass,true);}) .mouseout()函数(){即. AddRemoveClass($(this),activeClass,false);}) ;itemElem.appendTo(this.getElem().查找('。内容项目');} ;
(四),最后总结
(1),面向对象的思考方式合理分析功能需求。
(2),以类的方式来组织我们的插件逻辑。
(3),不断重构上面的实例,如何进行合理的重构那?不要设计过度,要游刃有余,推荐的方式是过程化设计与面向对象思想设计相结合。
(4),下篇文章中会扩展相关功能,比如"模式"这个属性,为'1'时支持检验盒多选模式,现在只是默认下拉模式。
看我本文,是不是要比上一篇代码优秀了很多呢,小伙伴们自己做项目也应该多想多做,尽量使自己的代码更加的合理。
版权声明:JavaScript插件化开发教程(六)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。