<span class="num">
<i class="vary-num">0i>/<i>10i>
span>
div>
JS代码是这样的:
1 2 3 4 5 6 7
| function changeInputValNum(id,num){ var valNum = $(id).val().length; if(valNum > num){ return; } $(id).next().find(".vary-num").html(valNum); }
|
一个全局函数changeInputValNum
暴露在全局空间window
下,而且每次onkeyup
事件的时候都会重新获取元素,非常浪费资源。还要给每个输入框加个id
,相信开发人员最不喜欢的一个就是起名字,什么id
啊,function
啊,等等。如果在外部需要重新更改输入框里面的内容,那么数字就变不了。总之,没有对外提供任何接口,以后加功能还得重写,还得考虑其它的相同组件没问题的运行,不方便。
既然组件有问题,那么重构开始了,下面贴上重构后的代码(展示了主要的,需要下载请点击):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| (function(root) { var API = API || {};
var StringCounter = function(options) { };
StringCounter.defaults = { max: 20, min: 0, size: 0, remains: 20, onchange: null };
StringCounter.prototype.init = function() { };
StringCounter.prototype.calculate = function() { };
API.StringCounter = function(options) { return new StringCounter(options); };
$(document).ready(function() { $(document).on('click.StringCounter', '.J_StringCounter', function(event) { event.preventDefault();
new StringCounter({ element: this, onchange: function() { var elem = this.$element;
elem.next('.num').find('.vary-num').text(this.size); } }); }); });
root.API = API; }(this));
|
HTML结构修改成了这样:
1 2 3 4 5 6
| <div class="input-num"> <input type="text" class="form-control J_StringCounter" maxlength="20" /> <span class="num"> <i class="vary-num">0i>/<i>20i> span> div>
|
采用面向对象的设计方法,初始化一次搞定,而且对于以后的结构如果变了,这个组件照样可以使用,只需要修改一下onchange
回调函数就行了。在上面的JavaScript代码中对外提供了一个统一调用接口API
,每次调用API.StringCounter
返回的都是构造函数StringCounter
的一个实例。这样就可以直接在外面使用prototype
原型链上面的方法了。
在项目中当然还有其它的组件都有类似的问题,需要的基本都给重构成面向对象的组件了。上面只是以一个小功能组件为例,提供重构的方法和思路。下面聊聊去除不可维护的代码。
去除不可维护的代码
什么是不可维护的代码呢?看下面:JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| function saveStaffForm(){ if($("#saveStaffBtn").prop("disabled") == true){ return; } if(!userNameCheck("userName","账号")){ return } if(!pwdCheck("userPwd","密码")){ return } if(!peopleNameCheck("pepName")){ return } if(!onEmptyCheck("time","出生日期")){ return } if(!onEmptyCheck("pepPost","职位")){ return } if(!onEmptyCheck("campusval","校区")){ return } if(!contactPhoneNumCheck("pepPhone")){ return } $("#saveStaffBtn").prop("disabled"); $.ajax({ url : "", data:{}, type : "post", dataType : "json", success : function(data) { }, error : function() { } }); }
|
HTML(表单的保存按钮):
1
| <button class="btn btn-large btn-primary" id="saveStaffBtn" type="button" onclick="saveStaffForm();">保存button>
|
这是一个表单提交的页面,有很多的验证校验,而且类似这样的表单提交页面很多。看到那么多的 if
和 return
真的有种想撞墙的冲动。压根就没法维护了,而且如果验证变了,那还得加 if
?~_~
解决方法:使用成熟的表单验证,我使用的是jquery-plugin-validate,这个验证插件非常方便,可以自定义验证规则,提供多种验证方式,还可以配合表单提交一起使用,非常方便。具体使用方法可以参考jquery-plugin-validate。上面写的很详细,一看就明白了。
去除不用和不良好的插件
考虑到项目只需要兼容到IE9,不用考虑IE8以下(福音啊),我果断地去掉了jQuery的placeholder
插件,去除了多余的组件。项目中有很多的弹窗,像alert
提示类型的,confirm
确认提示类型、还有加载一段HTML
的。没重构之前使用的是bootstrap的modal
插件。虽然功能还凑合着使用,但是没有拖拽,自定义按钮、自定义位置、加载iframe等功能。还是不能满足项目需求,于是我将公共dialog组件果断换成了artDialog。关于artDialog组件的功能强大毋庸置疑,使用方法可以参考https://github.com/aui/artDialog。
重构一次代码,会总结一些技术经验,有助于提高自己的编码能力。在项目重构过程中会遇到的问题远不止以上几点,上面只是简单说了一部分,以后可能会出一些关于CSS的重构,以及基于npm
前端静态资源管理等方面的的文章。最后附上本文的源码链接,希望能对读者有所帮助。