php 插件化开发模式,JavaScript_JavaScript插件化开发教程(六),一,开篇分析 今天这篇文章 - phpStudy...

本文详细介绍了JavaScript插件化的开发过程,通过一个具体的组件实例,分析了代码存在的问题,如重复代码过多、职责划分不清晰等,并提出了重构方案。重构主要目标是进行功能点的抽象、职责划分,以提高代码的可读性和可维护性。作者展示了重构后的代码,强调了面向对象思考和合理组织代码的重要性,并预告将在后续文章中扩展组件功能,例如支持多选模式。
摘要由CSDN通过智能技术生成

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*/

/* update 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 ;

} ;

/* update 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 = $("

var activeClass = ("0" == item["disabled"]) ? "item-hover" : "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多选模式,现在只是默认下拉模式。

看我本文,是不是要比上一篇代码优秀了很多呢,小伙伴们自己做项目也应该多想多做,尽量使自己的代码更加的合理。相关阅读:

PHP实现长文章分页实例代码(附源码)

如何解决在jsp页面上导入.xls文件报错问题

php操作memcache缓存方法分享

详解Java设计模式编程中的中介者模式

C++读取INI配置文件类实例详解

Javascript模块化编程详解

centos6.5中安装mongodb简明总结

Win10 Mobile将迎来原生的Windows10通知同步功能

SMTP客户端未通过身份验证等多种错误解决方案分享

Win10 TH2预览版10586桌面水印消失怎么办?预览版需重注册

win10系统字体显示正常但是第三方软件字体模糊该怎么办?

gridview 行选添加颜色和事件

静态gb2312编码在项目传值出现中文乱码现象

已安装KB3035583补丁却没有获取Win10预订图标的解决方法

Object 对象插件 Preload Images with Status Bar and 1.1.0 预载图片,有进度显示,完成以后跳转到新页面,只支持静态页。 History Navigation.mxp 插入一个可设置前进、后退和刷新的按钮。 Sound 2.21.mxp 插入一个声音可设置循环数。 Online Html Editor.mxp 创建一个“Html”在线编辑器。 Cheese Master Suite.mxp 插入雪花等网页特效。 Flash Image.mxp 当鼠标经过图片上面的时候,图片会慢慢变的清晰。 Date Stamp.mxp 显示最后更新日期。 Cheese Master Suite-Bouncy Balls.mxp 插入一个可以跟随鼠标运动的图片。 CN Insert Greeting.mxp 为你创建在早、中、晚不同时段出现不同的问候语。 Expandable Outlines.mxp 建立一个目录树样式的导航菜单。 Flash Text.mxp 使文字象打字效果一样显示。 Letterbox Frameset.mxp 创建一个中间的框架总是居于浏览器窗口正中位置 Auto Copyright.mxp 插入一个自动更新时间的版权符号。 Marquee.mxp 插入一条滚动的文字,并且可以设置它滚动的方向。 Background that Fit.mxp 把一张图片作为背景铺满整个浏览器,可随浏览大小的变自动调整。 URL into layer.mxp 在你的网页里面插入一个层,并且在这个层里面导入另一个页面的URL。 Transition.mxp 设置网页背景转换效果 Save Password Login form.mxp 保留登陆的姓名和密码,并且可以为其设置保留时间。 Scrolling Status Bar.mxp 在浏览器的地址栏里逐条显示信息。 Count up.mxp 当一个访客浏览你的网页时,看该访客在你的网页上停留多长时间。 Alternating Row Colors.mxp 设置表格的背景色,使之以交互的颜色来区分表格的行。 Go Back or Forward.mxp 该插件的功能相当于浏览器工具栏标准按钮上的“前进”和“后退”。 IE5.5 Custom Scrollbars.mxp 用来改变IE浏览器滚动条的颜色的 Command 命令插件 Auto Default Form Field.mxp 可设置自动清除表单文本参数。 Style switcher Lite.mxp 早晚载入不同的样式。 IE Link Scrubber.mxp 消除链接的虚线框。 Advanced Random Images.mxp 随机显示图片。 Page Transitions.mxp 设置页面的转场效果。 dHTML Scrollable Area.mxp 插入一个可以手动的滚动看板 Random Rollover.mxp 在同样大小的主图片下面可以设置多幅随机翻转的图片。 Move Window.mxp 设置浏览器窗口在屏幕上显示的位置。 Resize Window.mxp 设置浏览器窗口的大小。 Show New.mxp 设置图片在页面中显示的时间,超过设置的时间该图片将不再显示。 HotKey Jump.mxp 创建热键跳转,按键盘上的一个你设置好的键就会转到另一页。 Set IE Scrollbars.mxp 设置“IE”滚动条的显示和隐藏。 Float Image.mxp 在页面中插入一个倒处飘浮的图片。 No Way Back.mxp 在页面中插入一组禁止后退的代码。 Right Click Menu Builder.mxp 设置鼠标右键的菜单。 Number Column.mxp 为表格添加序号,不支持动态表格。 Live clock.mxp 为我们插入一个动态的时钟。 Kaosweaver PHP Upload.mxp 把图片上传到你的网站。 PHP Date and time.mxp 该插件的功能比较强大,你可以用它来自由的设置时间格式。 Banner Image Builder.mxp 创建交替显示的图片,并且可以为每一张图片设置链接指向。 Behavior 行为插件 Popup Link 1.4.3.mxp 打开浏览器的窗口,可设置尺寸并定位显示位置。 Length validator 1.2.0.mxp 限制文本域输入的字符数。 Swap Flash.mxp 像轮换图片一样轮换Flash动画,注意:要先点选页面中的Flash。 Random Links 1.2.3.mxp 随机载入网页。 FX Password Generator 1.0.2.mxp 在文本域里生成密码。 check form.mxp 检查表单行为。 Submit Form.mxp 当你在下拉菜单中选择一项条件后会自动转向另一页。 Form Auto Clear.mxp 自动清除文本域里面的默认文字。 Linecraft Highlight-Restore Form.mxp 当鼠标点击或离开一个表单元素时,改变其背景和文字颜色。 Typewriter.mxp 在层里面设置一行文字,该文字以打字的效果出现。 List Menu Rewrite.mxp 使一个下拉菜单与另一个下拉菜单相关联。 Random URL.mxp 使一组URL随机显示。 Toggle Checkboxes.mxp 检查多选框。 Float Layer.mxp 定位层的横向流动,不管浏览器横向大小怎样变,该层均不会改变位置。 Popup Message.mxp 在“提交”按钮上添加注释。 Compare Fields.mxp 对比两个表单的内容是否相同,多用于密码验证。 Fade Link.mxp 使链接的颜色缓慢改变,是一种柔和的转变效果。 Dynamic Styler.mxp 动态改变页面的背景颜色。 Fluid Browser Window.mxp 设置浏览器窗口由小到大动态打开。 Pagetime.mxp 设置在什么时间载入什么页面。 Just-So Picture Window.mxp 设置一幅图片在新窗口中打开,点击任何部位就可以关闭这个窗口。 Layer Transitions.mxp 设置层的转换效果的,与前面介绍的页面转换效果类似。 Persistent Layers.mxp 使层固定在浏览器中的某个位置,不管页面滚动,都会保持在原来位置不变。 Server Behavior 服务器行为插件 Send Email PHP.mxp 发送“Email” Make Hyperlink.mxp 使细节页面的网址自动俱备超链接功能。 FX DWLCounter 1.1.1.mxp 制造下载计数器。 FX PHP Missing Tools.mxp 制造详细页。 FX PHP UserAuthent 1.3.0.mxp 制造登入和登出。 PHP Upload.mxp 上传一个文件到服务器。 PHP Login.mxp 是可以设置“Sessions”的登陆插件。 Newline Blank php.mxp 保留上传文件的换行和空格。 Insert Retrieve ID PHP.mxp 插入一个可以找回的“ID”。 FX PHP Sessions12.mxp 设置“Sessions”。 FX PHP Cookies11.mxp 设置“Cookies”。 Horizontal Looper PHP.mxp 可以设置记录集横向显示。 Alternate Row Colors.mxp 设置动态背景交替颜色,还可以设置当鼠标经过时改变颜色。 Navigation Builder.mxp 设置类似“prev | 1 | 2 | 3 | 4 | next的导航栏。 Random Region.mxp 随机显示记录,当你刷新一次页面就重新显示一个记录。 Visit counter.mxp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值