最近写了个网站,当时借鉴了很多相关网站前端技术,为了让客户的体验更加好,我在网站前端加入了相当多的校验代码,因此代码显的特别臃肿。虽然开发过程中我将前端代码重构了三次,但是我还是对我原来写的代码不满意。五一假期我好好复习了下javascript的知识,这里试着总结下我对代码不满意的地方,大致有以下几点:
1) 我一直都在琢磨jQuery源码的写法,觉得jQuery是我见过写的最棒的代码,因此代码里的写了大量的普通的function,这个很不符合jQuery的风格,这个让我很不爽。
2) 不同的页面其实有很多类似的操作,这些操作是可以抽取成为公共的方法,例如:不同页面里的文本框、下拉框、多选框和单选框,它们大多都会有blur、focus和keyup事件,如果我一个个绑定这些事件,真是一件很不爽的事情,而且最终的代码会让人感觉很没有档次,因此事件绑定应该要好好的封装下,这样代码的质量会更高,通用性更好。
3) 页面里的js代码过多。我现在写前端页面总会考虑我这么开发会让我的页面运行的更快吗?提高页面的相应速度的方法很多,但是有几点只要你在开发时候处处留心很容易做到,例如:减小页面的大小,但是如果你的页面的js代码过多了,页面的大小会变大,或多或少会影响到页面在网络中传输的速度;好的js代码应该是尽力的把统一的方法写到外部的js文件,而且这个js文件数量要尽量少。而我的页面里js代码过多,这也是一个败笔。
4) 我一直都觉得用json的格式定义javascript变量是一个十分优雅的编程模式,但是这个技能我并不太熟练,因此当项目很赶的时候我不自觉的还是按原来的套路写js代码,这样的代码现在回头看看,真是有点原始(幼稚)。
5) 既然是用jQuery框架做开发,那么代码应该尽量发挥出jQuery代码的特点,用最好的jQuery风格的代码去开发,才会让你的代码显得优质(也许jQuery代码的效率和原生态的js代码有性能的差别,不过我们平时做的项目里,jQuery的效率的缺陷基本都可以忽略不计),多去思考如何让你写的jQuery代码写的更好,是对你使用语言的尊重,这种尊重一定能让你进步的更快。
五一节我想到了用jQuery插件的模式重新封装我的代码,让我的代码和jQuery框架融为一体,此外尽力把公共的方法都抽取出来放到统一的js文件里,页面最好只留一定要写到页面里的代码。
下面就是我写的代码,首先还是先看看我的目录结构:
index.html的代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>UMSS JQUERY MAIN JS File</title> <script type="text/javascript" src="js/jquery-1.7.1.js"></script> <script type="text/javascript" src="js/jquery.umss.js"></script> <link type="text/css" rel="stylesheet" href="css/jquery.umss.css" /></link> </head> <body> <fieldset> <legend>用户注册</legend> <form> <p> <label for="email"> 电子邮件:</label><input type="text" size="24" id="email" name="email"/> <span id="emailmsg" name='' style="color:#F00"></span> </p> <p> <label for="mphone"> 手机号码:</label><input type="text" size="24" id="mphone" name="mphone"/> <span id="mphonemsg" name='' style="color:#F00"></span> </p> <p> <label for="onepwd"> 密 码:</label><input type="password" size="24" id="onepwd" name="onepwd"/> <span id="onepwdmsg" name='' style="color:#F00"></span> </p> <p> <label for="twopwd">密码again:</label><input type="password" size="24" id="twopwd" name="twopwd"/> <span id="twopwdmsg" name='' style="color:#F00"></span> </p> <p> <label> 验证码:</label><input type="text" id="code" name="code" maxlength="6" size="24"/> <input type="text" id="codeimg" name="codeimg" class='unchanged' readonly="readonly"/> <span id="codemsg" name='' style="color:#F00"></span> </p> <p> <input type="button" value="确 定" id="btn" name="btn"/> </p> </form> </fieldset> </body> </html> <script type="text/javascript"> $(document).ready(function(){ bindFormAttrEvt(); }); function bindFormAttrEvt(){ var formattrs = ['#email','#mphone','#onepwd','#twopwd','#code','#codeimg','#btn']; var evttypes = 'focus blur keyup click'; var evtMethods = {'focus':evtFocusMethod,'blur':evtBlurMethod,'keyup':evtKeyUpMethod,'click':evtClickMethod}; // 绑定事件 $.bindEvtByTypeUmss(formattrs,evttypes,evtMethods); // 初始化验证码 $.createUmssCode($('#codeimg')); } // 点击(click)事件方法 function evtClickMethod(evt){ var objid = evt.target.id; switch(objid){ case 'codeimg': $.createUmssCode($('#codeimg')); break; case 'btn': var flag = true; var checkarrs = ['email','mphone','onepwd','twopwd','code']; $.each(checkarrs,function(i,data){ var evt = {'target':{'id':data}}; if (flag){ flag = evtBlurMethod(evt); } }); console.log(flag); if (flag){ alert('数据提交成功!!!!!'); } break; default: break; } } // 失去焦点(blur)事件方法 function evtBlurMethod(evt){ var objid = evt.target.id; /*if (evt.target.id != null){ objid = evt.target.id; }else{ objid = evt; }*/ switch(objid){ case 'email': if ($.isEmailUmss($('#email').val()) == false){ $('#emailmsg').text('电子邮件格式不正确!'); return false; }else{ $('#emailmsg').text('恭喜你!电子邮件格式正确!'); return true; } break; case 'mphone': if ($.isMPhoneUmss($('#mphone').val()) == false){ $('#mphonemsg').text('手机号码不正确!'); return false; }else{ $('#mphonemsg').text('恭喜你!手机号码正确!'); return true; } break; case 'onepwd': if ($.isPwdLengthMinUmss($('#onepwd').val())){ $('#onepwdmsg').text('密码长度不能少于6个字符!'); return false; }else if ($.isPwdLengthMaxUmss($('#onepwd').val())){ $('#onepwdmsg').text('密码长度不能多于32个字符!'); return false; }else if ($.pwdFormatCheckUmss($('#onepwd').val())){ $('#onepwdmsg').text('密码由6~32位不连续的数字或英文字母组成!'); return false; }else{ $('#onepwdmsg').text('恭喜你!密码格式正确!'); return true; } break; case 'twopwd': if ($('#onepwd').val() != $('#twopwd').val()){ $('#twopwdmsg').text('两次密码不一致!'); $('#twopwd').val(''); return false; }else{ $('#twopwdmsg').text('恭喜你!密码一致的哈!'); return true; } break; case 'code': if ($('#code').val() != $.umsscode){ $('#codemsg').text('验证码输入不正确!'); return false; }else{ $('#codemsg').text('恭喜你!验证码输入正确!'); return true; } break; default: break; } } // 焦点(blur)事件方法 function evtFocusMethod(evt){ var objid = evt.target.id; switch(objid){ case 'email': $('#emailmsg').text('请输入电子邮件!'); break; case 'mphone': $('#mphonemsg').text('请输入手机号码!'); break; case 'onepwd': $('#onepwdmsg').text('请输入密码!'); break; case 'twopwd': $('#twopwdmsg').text('请输入密码again!'); break; case 'code': $('#code').text('请输入验证码!'); break; default: break; } } // 键盘输入(keyup)事件 function evtKeyUpMethod(evt){ var objid = evt.target.id; switch(objid){ case 'email': $('#emailmsg').text('你输入的字符长度是:' + $('#email').val().length); break; case 'mphone': $('#mphonemsg').text('你输入的字符长度是:' + $('#mphone').val().length); break; case 'onepwd': $('#onepwdmsg').text('你输入的字符长度是:' + $('#onepwd').val().length); break; case 'twopwd': $('#twopwdmsg').text('你输入的字符长度是:' + $('#twopwd').val().length); break; case 'code': $('#codemsg').text('你输入的字符长度是:' + $('#code').val().length); break; default: break; } } </script>
jquery.umss.js的代码:
// 为了避免函数、对象以及变量和jQuery其他的函数、对象及变量冲突,所有方法都以Umss结束 ;(function($){ var emailregex = /^([a-zA-Z0-9_-]{1,})((.[a-zA-Z0-9_-]{1,}){0,})@([a-zA-Z0-9_-]{1,})((.[a-zA-Z0-9_-]{1,}){1,})$/, mphoneregex = /^1[3|4|5|8][0-9]\d{4,8}$/, pwdregex = /^[a-zA-Z0-9]{6,32}$/; $.extend({ 'umsscode':'', 'isEmailUmss':function(val){ return emailregex.test(val); }, 'isMPhoneUmss':function(val){ return mphoneregex.test(val); }, 'isPwdLengthMinUmss':function(val){ return (val.length < 6)?true:false; }, 'isPwdLengthMaxUmss':function(val){ return (val.length > 32)?true:false; }, 'pwdFormatCheckUmss':function(val){ return !pwdregex.test(val); }, 'createUmssCode':function(jobj){ $.umsscode = ''; var codelen = 6;//验证码的长度 var selectChar = new Array(0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');//所有候选组成验证码的字符,当然也可以用中文的 for (var i = 0;i < codelen;i++){ var charindex = Math.floor(Math.random()*36); $.umsscode += selectChar[charindex]; } jobj.val($.umsscode); }, 'bindEvtByTypeUmss':function(formattrs,evttypes,evtMethods){ $.each(formattrs,function(ind,obj){ $(obj).bind(evttypes,function(evt){ var type = evt.type; switch(type){ case 'blur': evtMethods.blur(evt); break; case 'focus': evtMethods.focus(evt); break; case 'keyup': evtMethods.keyup(evt); break; case 'click': evtMethods.click(evt); break; default: break; } }); }); } }); })(jQuery)
jquery.umss.css的代码如下:
#codeimg{ background-image:url(../images/code.jpg); font-family:Arial; font-style:italic; color:Red; border:0; padding:2px 3px; letter-spacing:3px; font-weight:bolder; cursor:pointer; } .unchanged{ border:0; width:80px; } form p { margin-left:300px; } form p input[type='button']{ margin-left:150px; }
这里的代码还存在缺陷,但是比我早先写的代码要好多,今天把它贴出来和大家交流下,希望js的大牛们能好好指点下。
为了以这样的方式写出代码,我研究了下jQuery插件技术,发现jQuery插件技术还是非常有内涵的技术,下篇里我就会和大家好好聊下jQuery的插件技术。
(注意:代码最好在firefox或是chrome里运行,代码里还存在一点小错误,我在下篇里会指出并修复)
代码下载链接:
http://files.cnblogs.com/sharpxiajun/jqumss.zip