使用此验证插件,我们只需要新建一个实例对象,同时传入一个json对象就行了,这里我们只传入了两个属性:checkItem和callback。下面的代码解析,我们就按照这个例子来。
var verify =new Validator({
checkItem:[ {"element":"#endTime","required":false,"rule":[{"reg":"int","errMsg":lang('org.userStrategy.end_with_int')}]},{"element":"#ruleMboxCapacity","required":true, "rule": [{"reg":"int","minValue":1,"maxValue":100}]},
{"element":"#endTime","required":false,"rule":[{"reg":"int","errMsg":lang('org.userStrategy.int_gez'),"minValue":1}]},
{"element":"#ruleIsMboxCapa","rule":[{"reg":"no","childElement":"#ruleMboxCapacity"}]} ], calback:function(){ if($("#startTime").val()==""){ return { "element":"#startTime", "status":false, "errMsg":lang('org.userStrategy.sdate_not_null') } } if($("#endTime").val()==""){ return { "element":"#endTime", "status":false, "errMsg":lang('org.userStrategy.edate_not_null') } } return { "status":true } } });调用Validator实例对象verify.getVerifyStatus(),如果返回true,就代表你在checkItem传入的元素验证全部通过了,如果返回false,就代表还有元素验证没有通过。
var Validator = function(options){
options = options || {"checkItem":null,"verifyCallback":null}; //options = {checkItem:[], callback: function(){}} this.barColor = ["#aa0033", "#ffcc33", "#6699cc", "#008000"]; this.levelTitle = ["不符合规则","弱","中","强"]; this.checkItem = options.checkItem || this.html2Json(); //这里我们有checkItem属性,因此不会调用html2Json方法 this.showPosition=options.showPosition || "right"; //默认为right this.verifyCallback = options.calback ;//自定义验证的回调函数; this.init(); }; var hash_rule={}; Validator.prototype = { init:function(){ var p = this; for(var i = 0 ;i<this.checkItem.length;i++){ //遍历checkItem数组 var ruleInfo = this.checkItem[i]; var input = $(ruleInfo.element); //数组中的每一项是一个json对象,其中element属性值是页面上元素节点的id input.off(); //移除此元素上通过on绑定的所有事件 var inputType = input.attr("type"); //得到此元素的类型 if(!ruleInfo.rule){ //查看此json对象是否有rule属性值,如果没有,就忽略,如果有,就继续判断 continue; } //绑定文本框的失去焦点事件,当失去焦点后判断文本框的内容是否合法 if ((inputType == "text" || inputType == "password")) { //如果元素的类型是text或是密码框 input.bind("blur", function(){ //就给此元素绑定blur事件 p.event._blur(this, p) }); } if(inputType =="checkbox" || inputType=="radio"){ //如果元素的类型是checkbox多选框或者是radio单选框 var childElementList = ruleInfo.rule[0].childElement; //rule属性也是数组,选取它的第一项,看它是否有childElement属性值 if(typeof(childElementList)=="string"){ //这里只有checkItem数组中的第四项有 childElementList=[childElementList]; ruleInfo.rule[0].childElement = childElementList; //把字符串转换成数组:"childElement":["#ruleMboxCapacity"] } if(!input.is(":checked")){ //如果元素checkbox或radio没有被选中,就进入if语句 for (var j = 0; j < childElementList.length; j++) { //就把设置它的子元素的属性disabled和noVerify $(childElementList[j]).attr("disabled", "true"); //这里的意思其实就是如果父元素没有被选上,那么子元素当然是不可用的,同时也不需要验证 $(childElementList[j]).attr("noVerify","1"); } } input.bind("click",function(){ //给元素checkbox或radio绑定click事件 var _ruleInfo = hash_rule[$(this).attr("guid")]; if(!_ruleInfo){ return; } var childElementList = _ruleInfo.rule[0].childElement; if(typeof(childElementList)=="string"){ childElementList=[childElementList]; } if(!$(this).is(":checked")){ //如果点击radio或checkbox后,元素没有被选择上for (var z = 0; z < childElementList.length; z++) {
$(childElementList[z]).attr("noVerify","1"); //就设置它的子元素全部为不可用,并且不验证 $(childElementList[z]).attr("disabled","true"); p._hideMessage($(childElementList[z])); //隐藏错误信息 } }else{ for (var z = 0; z < childElementList.length; z++) { $(childElementList[z]).removeAttr("noVerify"); $(childElementList[z]).removeAttr("disabled"); } } }) } //判断当前元素是否是密码框 if(inputType=="password" ){ var isCompare= false; for(var z = 0 ;z<ruleInfo.rule.length;z++){ if(ruleInfo.rule[z].reg =="compare"){ //看一下checkItem中的reg的值是否是compare,如果是,就代表是密码比较框,也就是你的确认密码框 isCompare=true; } } if (!isCompare) { //如果就是密码框 if (ruleInfo.isAddTitle != false) { //如果checkItem中有isAddTitle属性值,并且不为false p._addPasswordHtml(input);//给密码框加上强\弱\中的提示HTML input.attr("maxLength","30"); //最多输入30个字符 input.bind("keyup", function(){//绑定事件,判断每次输入后的密码等级 p.event._bindPassWord(this, p) });}
} } if (ruleInfo.title) { //如果checkItem数组中的每一个json对象中有title属性,就给此元素绑定click事件。 $(input).bind("click", this._click); } //生成一个时间戳,复制给元素节点的guid属性中.然后将每个元素节点对应的验证规则存储在Hash中,后面就只要在hash中就能知道此元素需要验证的规则了. var guid = new Date().getTime()+Math.floor(Math.random()*1000); input.attr("guid",guid); hash_rule[guid]=ruleInfo; } },//文本框的事件处理
event:{ _click :function(){ var guid = $(this).attr("guid"); var inputObj = hash_checkObj[guid]; _showMessage($(this),inputObj.title); }, //所有文本框的失去焦点的事件处理 _blur :function(element,This){ //元素节点的类型为text或password时,当给此元素触发blur事件时,会触发此方法的执行 if($(element).attr("noVerify")=="1"){ //判断此元素是否需要验证,等于1,就代表不用验证 This._hideMessage($(element)); //不需要验证,就代表需要隐藏此元素的错误提示 return true; } if($(element).parents("div:eq(0)").is(":hidden")){ //如果此元素的祖先元素中第一个div元素是隐藏的,就不用验证,直接隐藏错误提示 This._hideMessage($(element)); return true; } var result = {}; switch($(element).attr("type")){ case "text": result = This.check._Input(element); //验证此框填的内容是否合法 break; case "checkbox": case "radio": result = This.check._Checkbox(element,This); break; case "password": result = This.check._Passwod(element,This); //如果是密码框 break; } if(!result.status){ //如果返回的状态为false,就代表错误,然后把错误信息显示出来 This._showMessage($(element),result.errMsg); }else{ This._hideMessage($(element)); } return result.status; }, //密码框的文本输入处理 _bindPassWord:function(element,This){ var options = {pwdMinLen: 6, pwdMaxLen: 30, pwdCheckType:1}; var paswordInfo = This.PwdCheck($(element).val(),options); if(!paswordInfo.status){ //如果返回的状态为false,就提示用户有什么问题 $(".pass_str_tips").html(paswordInfo.msg); $(".pass_str_tips").show(); }else{ //如果返回的状态是true $(".pass_str_tips").html("长度"+options.pwdMinLen+"-"+options.pwdMaxLen+"位半角字符(字母、数字、符号)组成,区分大小写"); } var levelTitle = $(".pass_str_txt").find("strong"); levelTitle.html(This.levelTitle[paswordInfo.SafeLevel]); //这里的levelTitle = ["不符合规则","弱","中","强"]; levelTitle.css("color",This.barColor[paswordInfo.SafeLevel]); //不同的提示,有不同的颜色$(".pass_str_bar").css({"width":(paswordInfo.SafeLevel+1)*45+"px","background-color":This.barColor[paswordInfo.SafeLevel]});
} }, addItem:function(item){ //增加验证的元素 item= item || this.html2Json(); this.checkItem = this.checkItem.concat(item); this.init(); }, //对所有类型的文本框的检查 check:{ //多选框 _Checkbox:function(element,This){ var result ={status:true,errMsg:""}; //return result; if ($(element).is(":checked")) { var guid = $(element).attr("guid"); var ruleInfo = hash_rule[guid]; if (ruleInfo.rule[0].childElement) { var childList = ruleInfo.rule[0].childElement; for (var i = 0; i < childList.length; i++) { if (!This.event._blur(childList[i], This)) { result.status = false; } } } result.errMsg = ruleInfo.rule[0].errMsg; } return result; }, //密码框有2种验证 一种是密码的规则校验,一种是密码的比较,因为要确认密码,所以有两个密码框 _Passwod:function(element,This){ var result ={ status:true , errMsg:"" }; var guid = $(element).attr("guid"); var ruleInfo = hash_rule[guid]; if (ruleInfo) { if (ruleInfo.isAddTitle != false) { //如果设置了isAddTitle属性,并且不为false var isCompare = false, compareId = ""; for (var z = 0; z < ruleInfo.rule.length; z++) { if (ruleInfo.rule[z].reg == "compare") { //如果是确认密码框 isCompare = true; compareId = ruleInfo.rule[z].compare; //如果是密码比较框,这里的compare的属性值就是被比较的那个密码框的id result.errMsg = ruleInfo.rule[z].errMsg || "两次输入的密码不一致"; } } if (!isCompare) { //如果是正常的密码输入框 var options = { pwdMinLen: 6, pwdMaxLen: 30, pwdCheckType: 1 }; var paswordInfo = This.PwdCheck($(element).val(), options); result.status = paswordInfo.status; result.errMsg = "密码不符合规则"; } else { result.status = ($(compareId).val() == $(element).val() ? true : false); //如果两个密码框的值一样,就返回true } } else{ return This.check._Input(element,ruleInfo); } } return result; }, //自定义的列表框 _List:function(element){ var result ={ status : false , errMsg : "" }; var guid = $(element).attr("guid"); var ruleInfo = hash_rule[guid]; if($(element).children().length>0){ result.status=true; } result.errMsg=ruleInfo.rule[0].errMsg; return result; }, //普通文本框 _Input:function(element,rule){ var result ={ status : true , errMsg : "" }; var guid = $(element).attr("guid"); var ruleInfo = rule ? rule : hash_rule[guid]; //取到此元素在checkItem中的验证规则 if(!ruleInfo){ return; } var inputType = $(element).attr("type"); var val = $.trim($(element).val()); var required =true; if(ruleInfo.required==false){ //是否必须存在值,默认为true,也就是默认文本框必须存在值 required=false; } if (required && val == "") { result.status = false; result.errMsg = "该项不能为空"; return result; } if(util.Reg.isLegitimacy(val) && inputType != 'password'){ //如果不是密码框,同时输入框中的值有非法符号 result.status = false; result.errMsg = "输入值中含有非法符号"+$.unique(val.match(/[%\/\\\'\"&<\>|\^]/igm)).join(""); return result; } if (val!="") { var rule = ruleInfo.rule; for (var i = 0; i < rule.length; i++) { switch (rule[i].reg) { case "empty": result.status = !util.Reg.isEmpty(val); break; case "int": result = this._int(val,rule[i]); //必须为int型 break; case "number": result.status = !isNaN(val); break; case "username": result = this._userName(val); break; case "chinesename": result.status = util.Reg.isInt(val); break; case "mobile": result.status = util.Reg.isMobile(val); break; case "tel": result.status = util.Reg.isTel(val); break; case "email": result.status = util.Reg.isEmail(val); break; case "demail": result.status = util.Reg.isDomainEmail(val); break; case "domain": result.status = util.Reg.isDomain(val); break; case "ip": result.status = util.Reg.isIp(val); break; case "smtp": result.status = util.Reg.isSmtp(val); break; case "compare": result.status =(val==$(rule[i].compare).val()?true:false); break; } result.errMsg = !result.errMsg?rule[i].errMsg:result.errMsg; //如果没有错误信息,就用用户传入的错误信息 } } return result; }, _int:function(val,rule){ var result = { "status":true }; if(!util.Reg.isInt(val)){ //如果不是数字,就直接返回false result.status=false; return result; } if (val!="" && (rule.maxValue || rule.minValue)) { //数字不能大于最大值,小于最小值 var iVal = parseInt(val); if (iVal > rule.maxValue) { result.errMsg = "最大值不能超过" + rule.maxValue; result.status = false; } else if (iVal < rule.minValue) { result.errMsg = "最小值不能小于" + rule.minValue; result.status = false; } } return result; }, _userName:function(val){ var result ={status:true,errMsg:""}; if(val.length<2){ result.status=false; result.errMsg="用户名最小长度为2"; }else if(val.length > 20){ result.status=false; result.errMsg="用户名最大长度为20"; }else if(util.Reg.isHaveChinese(val)){ result.status=false; result.errMsg="用户名不能包含中文"; } else if(!util.Reg.netname(val)){ result.status = false; result.errMsg = "帐号不合法"; } return result; } }, //添加密码框下面的安全级别提示的HTML _addPasswordHtml:function(element){ var passwordHtml = '<div class="verify-message pass_str" data-role="message">' +'<div class="pass_str_txt"><strong></strong>密码安全度:</div>' +'<div class="pass_str_line"><div class="pass_str_bar"></div></div>' +'<div class="pass_str_tips"></div></div>' element.after(passwordHtml); }, //显示错误信息 _showMessage:function(element,message,position){ element.addClass("erro-input"); var rule = hash_rule[element.attr("guid")] || {"position":"right"}; var position = position?position:(rule.position || "right"); if (!element.next().hasClass("errortip")) { //如果元素的下一个元素没有errortip类 element.parents("div:eq(0)").addClass("p_relative"); var top ="px"; var left ="0px"; if(position=="down"){ top = element.position().top+element.height()+10+"px"; //position() 方法返回匹配元素相对于父元素的位置(偏移)。该方法返回的对象包含两个整型属性:top 和 left,以像素计。此方法只对可见元素有效。left = (element.position().left-5)+"px";
}else{ top = element.position().top+"px"; left = (element.position().left+element.width()+20)+"px"; } element.after('<div class="errortip ml_5" style="top:'+top+';left:'+left+'">'+message+'</div>'); }else{ element.next().hasClass("errortip")?element.next().html(message):""; } }, //隐藏错误信息 _hideMessage:function(element){ if (element.prop("tagName") == "UL") { element.parent().removeClass("erro-input"); element.parents("div:eq(1)").find(".errortip").remove(); } else { element.parent().find(".errortip").remove(); element.removeClass("erro-input"); } }, //得到整个验证的状态,是否验证通过 getVerifyStatus:function(){ var status =true;; for(var i = 0 ;i<this.checkItem.length;i++){ var _element = $(this.checkItem[i].element); if(this.checkItem[i].rule[0].reg == "no"){ //如果元素本身不需要验证,那么验证它的子元素 _element = $(this.checkItem[i].rule[0].childElement); } //过滤掉本身不需要检验的元素 if (_element.attr("type")) { if (!this.event._blur(_element, this)) { //如果元素没有通过验证,就返回false status = false; } } else{ var tarName = _element.prop("tagName"); switch(tarName){ case "UL": var checkResult = this.check._List(_element) ; //如果验证的元素是ul,则需要验证它是否有子元素,如果有,就返回true,没有就返回false if(!checkResult.status){ this._showMessage(_element.parents("div:eq(0)"),checkResult.errMsg); status =false; } break; case "DIV": break; } } } if(this.verifyCallback){ //如果有回调函数 var result = this.verifyCallback(); //就执行此回调函数 if(!result.status){ //如果回调函数返回的状态为false,就显示错误 this._showMessage($(result.element),result.errMsg); status = false; } } return status }, //得到指定文本框的验证状态,第一个参数是验证的对象,第二个参数代表是否显示错误信息 getSingStatus :function(element,isShowErr){ var result = this.check._Input(element,hash_rule[$(element).attr("guid")]); if(!result.status && isShowErr){ this._showMessage($(element),result.errMsg); } return result.status; }, //将写在文本框上的验证转换成JSON 然后解析; html2Json:function(){ var checkItem = []; $("[reg]").each(function(){ //对页面上所有具有reg属性的元素进行处理 var other = { "reg":$(this).attr("reg"), "errMsg":$(this).attr("errmsg") } if($(this).attr("maxValue")){ other.maxValue=$(this).attr("maxValue"); } if($(this).attr("minValue")){ other.minValue=$(this).attr("minValue"); } if($(this).attr("compare")){ other.compare = $(this).attr("compare"); } var rule = { "element":$(this), "position":$(this).attr("position") || "right", "required":!($(this).attr("required")?true:false), //如果此元素的required = false,那么就设置rule.required = true,就规定此元素不能为空。如果此元素的required = true,那么就设置rule.required = false。 "rule":[other] } if(other.reg=="empty"){ //如果元素的reg属性值为empty,那么就规定此元素不能为空 rule.required=true; } checkItem.push(rule); }) return checkItem; }, //密码的处理机制 PwdCheck: function (spwd, o) { //这里的o = {pwdMinLen: 6,pwdMaxLen: 30,pwdCheckType: 1},spwd为密码框中的值var p = this;
var NotContains = p.NotContains; //密码框中的值不能包括NotContains对象中定义的属性值p.sLevel = o.pwdCheckType; //1
p.VdPassword = {};p.VdPassword.pwdMinLen = o.pwdMinLen; //6
p.VdPassword.pwdMaxLen = o.pwdMaxLen; //30 p.VdPassword.level = o.pwdCheckType; //1 //获取密码框中的值 var spwd = spwd; var dic = [ "123456", "12345", "123456789", "password", "iloveyou", "rockyou", "1234567", "12345678", "abc123", "654321", "iloveu", "111111", "0" ];String.prototype.LTrim = function () {
return this.replace(/(^\s*)/g, ""); } String.prototype.RTrim = function () { return this.replace(/(\s*$)/g, ""); } String.prototype.Trim = function () { return this.replace(/(^\s*)|(\s*$)/g, ""); } String.prototype.replaceAll = function (s1, s2) { return this.replace(new RegExp(s1, "gm"), s2); } function getReturnValue(sLevel, sNcode) { //当密码框为空时,这里传入的是0,1。如果密码长度小于6,大于30,传入0,9。如果密码是常用的简单密码,传入0,2。密码为纯数字,传入1,0.密码包含中文,传入0,6.如果密码包含了空格,传入0,10.如果都不属于前面的情况,那么就传入undefined,0,这时sLevel为2或者3. if (sLevel == 0) { sLevel = 0; } else if (sLevel != 0) { //如果合法, 根据[字母,特殊字符,数字]得到密码的强度 sLevel = getStrongLevel(spwd); //如果密码有字母,特殊字符,数字三种,就返回3,有两种,就返回2,只有一种就返回1 } var ret = { SafeLevel: sLevel, NotifyCode: sNcode }; p.VdPassword.SafeLevel = sLevel; p.VdPassword.NotifyCode = sNcode; return setMsg(sNcode, sLevel);}
//设置密码验证后的提示信息
function setMsg(sNcode, sLevel) { //如果密码框为空,这里传入的是1,0。如果密码长度小于6大于30,这里是9,0。如果输入的密码是常用的简单密码,就传入2,0.如果密码为纯数字,这里传入0,1.如果密码包含中文,传入6,0.如果密码包含空格,传入10,0.如果前面的都不匹配,就代表密码没问题,传入0,2(或3)。 if(sNcode<9 || sNcode==10){ p.VdPassword.msg = App.$LANG("control.verify.pass_msg"+sNcode); } else if(sNcode == 9){ p.VdPassword.msg =util.text.format(App.$LANG("control.verify.pass_msg9"),p.VdPassword.pwdMinLen, p.VdPassword.pwdMaxLen); } if (sNcode != 0) { p.VdPassword.status = false; //返回false状态return p.VdPassword;
}//如果没有错误,但安全强度没有达到我们设置的要求,则返回false,并且提示用户,你输入的密码太简单了,等级太低了。
if (sNcode == 0 && sLevel < p.sLevel) { var mustLevel = p.sLevel; p.VdPassword.msg = App.$LANG("control.verify.pass_type_"+mustLevel); p.NotifyCode = 10; p.VdPassword.status = false; return p.VdPassword; } else if (sNcode == 0) { p.NotifyCode = 0; p.VdPassword.msg = ""; p.VdPassword.status = true; //返回true return p.VdPassword; }}
function isTrim(s){
if(s.replace(/ /g,"").length!=s.length){ return true; }else return false; }function getPwdProperty(pwd) {
var hasNum = false; var hasLetter = false; var hasSymbol = false; var s = pwd.toLowerCase(); var numStrs = "0123456789"; var letterStrs = "abcdefghijklmnopqrstuvwxyz"; var symbolStrs = "~!@#$%^&*()_-=+{}[]:\"|<>?,./;'\\"; var ch = ""; //判断是否有数字 for (var i = 0; i < s.length; i++) { ch = s.substr(i, 1); if (numStrs.indexOf(ch) != -1) { hasNum = true; break; } } //判断是否有字母 for (var i = 0; i < s.length; i++) { ch = s.substr(i, 1); if (letterStrs.indexOf(ch) != -1) { hasLetter = true; break; } } //判断是否有特殊符号 for (var i = 0; i < s.length; i++) { ch = s.substr(i, 1); if (symbolStrs.indexOf(ch) != -1) { hasSymbol = true; break; } } var ret = { HasNum: hasNum, HasLetter: hasLetter, HasSymbol: hasSymbol }; return ret; };function getStrongLevel(pwd) {
var pro = getPwdProperty(pwd); var hasNum = pro.HasNum; var hasLetter = pro.HasLetter; var hasSymbol = pro.HasSymbol;//没有数字,没有特殊字符,
if ((!hasNum) && (!hasSymbol)) { return 1; } //没有数字,没有字母 if ((!hasNum) && (!hasLetter)) { return 1; }//没有字母, 没有特殊字符
if (!(hasSymbol) && !(hasLetter)) { return 1; } //有数字,有字母,没特殊字符 if ((hasNum) && (hasLetter) && (!hasSymbol)) { return 2; } //有数字,没有字母,有特殊字符 if ((hasNum) && (!hasLetter) && (hasSymbol)) { return 2; } //没有数字,有字母,有特殊字符 if ((!hasNum) && (hasLetter) && (hasSymbol)) { return 2; } if (hasNum && hasLetter && hasSymbol) { return 3; } return 3; };var level; //密码的安全度 [ 弱 普通 安全 ]
/* 1.输入为空,直接返回安全度为 [ 0 ] */
if (spwd == "") { level = 0; ncode = 1; return getReturnValue(level, ncode); } /* 2.如果小于6或者大于30,密码长度不对,返回安全度为[ 0 ] */ if (spwd.length < parseInt(p.VdPassword.pwdMinLen) || spwd.length > parseInt(p.VdPassword.pwdMaxLen)) {level = 0;
ncode = 9;return getReturnValue(level, ncode);
}var smppwd = spwd; //密码框中的值
var dicpwd; for (var i = 0; i < dic.length; i++) { smppwd = spwd; dicpwd = dic[i]; // 3.如果密码为常用的简单密码, 返回安全度为[ 0 ] if (smppwd == dicpwd) { level = 0; ncode = 2; return getReturnValue(level, ncode); } }/* 4.[ NotContains : 密码不能等于这个对象的属性 ] */
if (NotContains) { if (NotContains.Account) { if (spwd == NotContains.Account) { level = 0; ncode = 3; return getReturnValue(level, ncode); } } if (NotContains.Mobile) { if (spwd == NotContains.Mobile) { level = 0; ncode = 3; return getReturnValue(level, ncode); } } if (NotContains.Alias) { if (spwd == NotContains.Alias) { level = 0; ncode = 3; return getReturnValue(level, ncode); } } }if (!/\D/.test(spwd)) { //5.密码为纯数字
level = 1; ncode = 0; return getReturnValue(level, ncode); }if (/.*[\u4e00-\u9fa5]+.*$/.test(spwd)) { // 6.包含了中文
level = 0; ncode = 6; return getReturnValue(level, ncode); }if(isTrim(spwd)){ //7.包含空格
level=0; ncode=10; return getReturnValue(level, ncode); } getReturnValue(level, 0); return p.VdPassword; } };代码中有一些调用了工具类util中的方法,将在下一个插件util中讲解。
加油!