;(function(){ ???/** 验证框架 checkFun* 使用方法: ???????* <input class="required" type="text" data-valid="isNonEmpty||isEmail" data-error="email不能为空||邮箱格式不正确" id="" /> ???* 1、需要验证的元素都加上【required】样式,当然这个required可以当参数传递,也可以自定义class类名* 2、@data-valid ???????验证规则,验证多个规则中间用【||】隔开,更多验证规则,看rules和rule,后面遇到可继续增加* 3、@data-error ???????规则对应的提示信息,一一对应* 调用方式checkFun({ ???formId:‘verifyCheck‘, //<验证formId内class为required的元素 ???checkClass:‘required‘, //<需要验证的DOM元素上默认class类名> ???onBlur:function(el,state){console.log(state)}, //<被验证元素失去焦点的回调函数,回调函数中包括当前输入框失焦后是否通过验证的状态true表示通过,false表示未通过> ???onFocus:null, //<被验证元素获得焦点的回调函数> ???onChange: null, //<被验证元值改变的回调函数> ???successTip: true, //<验证通过是否提示> ???resultTips:null, //<显示提示的方法,参数obj[当前元素],isRight[是否正确提示],value[提示信息]> ???clearTips:null //<清除提示的方法,参数obj[当前元素]> ????????????}) ?下面列举下实现的调用 ?//1.实现isNonEmpty,邮箱格式isEmail<input class="required" type="text" data-valid="isNonEmpty||isEmail" data-error="email不能为空||邮箱格式不正确" id="" /> ???//2.验证最小长度minLength与最大长度maxLength<input type="password" placeholder="密码" value="" class="required password" id="password" data-valid="isNonEmpty||minLength:3" data-error="密码不能为空||密码长度至少为3位"/>//3验证某个范围内between<input type="password" placeholder="密码" value="" class="required password" id="password" data-valid="isNonEmpty||between:3-5" data-error="密码不能为空||密码长度在3-5位"/>//4.验证两次密码是否输入一致isRepeat<div class="same"> ???<input type="password" placeholder="密码" value="" class="required password" id="password" data-valid="isNonEmpty||between:3-5" data-error="密码不能为空||密码长度在3-5位"/> ???<label class="focus valid"></label></div><div class="same"> ???<input type="password" placeholder="重复密码" value="" class="required password2" id="password2" data-valid="isNonEmpty||isRepeat:password" data-error="密码不能为空||两次输入的密码不一致"/> ???<label class="focus valid"></label></div>//5.验证密码强度level (使用方式跟minLength一样 level:3)//6.验证是否为手机号码isPhone//7.验证是否为纯中文isZh//8.验证身份证号码isCard ???//下面的方式原生调用方式,当然可以使用jquery触发点击事件document.getElementById(‘submitBtn‘).addEventListener(‘click‘,function(){ //点击提交按钮时验证 ????????if(!checkFun.click()) return; ?},false)*/ ???/** 深度拷贝 ????* @param p 拷贝的对象 ????* @param c c默认传递的对象,也可以不传 ????* @result 返回拷贝后的对象 ????* */ ???var extendCopy = (function f(p,c){ ???????var c = c || {}; ???????for (var i in p) { ???????????if(typeof p[i] === ‘object‘){ ???????????????c[i] = (p[i] instanceof Array) ? [] : {}; ???????????????f(p[i],c[i]); ???????????}else{ ??????????????? ???????c[i] = p[i]; ???????????} ???????} ???????return c; ???}); ???????var opts; ???var checkFun = function(config){ ???????????opts = extendCopy(config || {},ValCheck.defaults); ???????return (new ValCheck())._init(opts); ???} ???????function ValCheck(){ ???????//验证规则 ???????var rule = { ???????????phone:/^1\d{10}$/, ???????????email:/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/, ???????????card:/^((1[1-5])|(2[1-3])|(3[1-7])|(4[1-6])|(5[0-4])|(6[1-5])|71|(8[12])|91)\d{4}(((((19|20)((\d{2}(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(\d{2}(0[13578]|1[02])31)|(\d{2}02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[48])0229)))|20000229)\d{3}(\d|X|x))|(((\d{2}(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(\d{2}(0[13578]|1[02])31)|(\d{2}02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[48])0229))\d{3}))$/, //身份证号 ???????????????zh:/^[\u4e00-\u9fa5]+$///纯中文 ???????}; ???????????????this.rules = { ???????????isNonEmpty: function(value, errorMsg) {//不能为空 ????????????????????errorMsg = errorMsg||" "; ????????????????????????if (!value.length) return errorMsg; ??????????????????????}, ???????????minLength: function(value, length, errorMsg) { //大于 ????????????????????errorMsg=errorMsg||" "; ?????????????????????????????if (value.length < length) return errorMsg; ???????????????????????}, ???????????maxLength: function(value, length, errorMsg) {//小于 ?????????????????errorMsg=errorMsg||" "; ??????????????????????????????if (value.length > length) return errorMsg; ???????????}, ???????????between: function(value, range, errorMsg) {//大于小于 ????????????????errorMsg=errorMsg||" "; ??????????????????????????var min = parseInt(range.split(‘-‘)[0]); ???????????????var max = parseInt(range.split(‘-‘)[1]); ???????????????????????????if (value.length < min || value.length > max) return errorMsg; ???????????}, ???????????isRepeat:function(value, range, errorMsg){ //重复密码 ???????????????????errorMsg=errorMsg||" "; ???????????????????var curPswDomVal = document.getElementById(range).value; ???????????????if(value!==curPswDomVal) return errorMsg; ???????????}, ???????????????isPhone: function(value, errorMsg) { ???????????????????errorMsg=errorMsg||" "; ?????????????????????????????if (value!=null && value!=‘‘ && !rule.phone.test(value)) return errorMsg; ???????????}, ???????????isEmail: function(value, errorMsg) { ???????????????????errorMsg=errorMsg||" "; ?????????????????????????????if (value!=null && value!=‘‘ && !rule.email.test(value)) return errorMsg; ???????????}, ???????????level:function(value,range,errorMsg){//密码复杂程度 ???????????????errorMsg=errorMsg||" "; ???????????????var r=checkFun.pwdStrong(value); ???????????????????????????????????????if(range>4) range=3; ???????????????if(r<range) ?return errorMsg; ???????????????????????}, ???????????isZh: function(value, errorMsg) { ???????????????errorMsg=errorMsg||" "; ???????????????????????????????if (!rule.zh.test(value)) return errorMsg; ???????????}, ???????????isCard: function(value, errorMsg) { ???????????????errorMsg=errorMsg||" "; ???????????????if (!rule.card.test(value)) return errorMsg; ???????????}, ???????????????????}; ???} ???????//默认配置 ???ValCheck.defaults = { ???????formId:‘verifyCheck‘, ???//验证的ID ???????checkClass:‘required‘, //需要验证的DOM元素上默认class类名 ???????onBlur:null,//被验证元素失去焦点的回调函数 ???????onFocus:null,//被验证元素获得焦点的回调函数 ???????onChange: null,//被验证元素值改变的回调函数,回调参数为当前DOM元素 ???????successTip: true,//验证通过是否有提示 ???????resultTips:null,//验证提示的回调函数,传回参数obj[当前元素],isRight[验证是否通过],value[提示的值] ???????clearTips:null //清空提示的回调函数,传回参数obj[当前元素] ???}; ???????//验证初始化 ???ValCheck.prototype._init = function(config){ ???????var self = this; ???????self.allinputs = document.getElementsByClassName(ValCheck.defaults.checkClass); ???????self.allinputs = Array.prototype.slice.call(self.allinputs,0); ???????for(var item =0, len = self.allinputs.length; item < len; item++){ ???????????(function(i){ ???????????????self.allinputs[i].addEventListener(‘blur‘,function(e){ ???????????????????e.preventDefault(); ???????????????????var state = self.formValidator(self.allinputs[i]); ???????????????????config.onBlur ? config.onBlur(self.allinputs[i],state) : ‘‘; ???????????????????},false); ???????????????????????????????self.allinputs[i].addEventListener(‘focus‘,function(e){ ???????????????????e.preventDefault(); ???????????????????if(config.onFocus){ ???????????????????????config.onFocus(self.allinputs[i]); ???????????????????}else{ ???????????????????????var matched = []; //存放兄弟节点 ???????????????????????var n = (self.allinputs[i].parentNode || {}).firstChild; ???????????????????????for(; n; n = n.nextSibling){ ???????????????????????????if(n.nodeType === 1 && n !== self.allinputs[i]){ ???????????????????????????????n.innerHTML = ‘‘; ???????????????????????????} ???????????????????????} ???????????????????} ???????????????},false); ???????????????????????????????self.allinputs[i].addEventListener(‘change‘,function(e){ ???????????????????e.preventDefault(); ???????????????????config.onChange ? config.onChange(self.allinputs[i]) : ‘‘; ???????????????},false); ???????????})(item); ???????????????} ???} ???????/** 验证规则 ????* @param el 当前被验证的DOM元素 ????* */ ???ValCheck.prototype.formValidator = function(el){ ???????var self = this; ???????var validataString = el.getAttribute(‘data-valid‘); ???????if(validataString === undefined){ ???????????return false; ???????} ???????var validArray = validataString.split(‘||‘); ???????????????var errorString = el.getAttribute(‘data-error‘); ???????if(errorString === undefined){ ???????????return false; ???????} ???????var errorArray = errorString.split(‘||‘); ???????var ruleArray = []; ???????for(var i =0, j = validArray.length; i < j; i++){ ???????????ruleArray.push({ ???????????????funTitle:validArray[i], ???????????????errorMsg:errorArray[i] ???????????}); ???????} ???????return self.validataResult(el,ruleArray); ???} ???????/** 验证结果 ????* @param el 验证的DOM元素 ????* @param ruleArray 需要逐一验证的数组规则 ????* */ ???ValCheck.prototype.validataResult = function(el,ruleArray){ ???????var self = this; ???????for(var i = 0, rule; rule = ruleArray[i++];){ ???????????var applyArgs = rule.funTitle.split(‘:‘); ???????????var errorMsg = rule.errorMsg; ???????????var ruleFun = applyArgs.shift();//得到匹配删除的函数名 ???????????applyArgs.unshift(el.value);// 数组第一位插入value值 ???????????applyArgs.push(errorMsg); //最后插入出错信息 ???????????applyArgs.push(el); ???????????var result = self.rules[ruleFun].apply(el, applyArgs); ???????????if(result){ ???????????????opts.resultTips ? opts.resultTips(el, false, result) : self.resultTips(el, false, result); ???????????????return false; ???????????} ???????????????????} ???????opts.successTip ? ( ???????????opts.resultTips ? opts.resultTips(el,true) : self.resultTips(el, true) ???????) : self.clearTip(el); ???????return true; ???????} ???????/** 验证信息的显示 ????* @param el 当前被验证的DOM元素 ????* @param isRight 验证是否通过, false=未通过 ?true=验证通过 ????* @param value 提示信息 ????* */ ???ValCheck.prototype.resultTips = function(el, isRight, value){ ???????var cls = ‘el_error‘; ???????var reg = new RegExp(‘(\\s|^)‘ + cls + ‘(\\s|$)‘,"g"); ???????value = value || ‘‘; ???????if(!isRight){ ???????????if(!el.className.match(reg)){ ???????????????el.className += ‘ ‘ + cls; ???????????} ???????}else{ ???????????if(el.className.match(reg)){ ???????????????el.className = el.className.replace(reg,‘‘); ???????????} ???????} ???????????var matched = []; //存放兄弟节点 ???????var n = (el.parentNode || {}).firstChild; ???????for(; n; n = n.nextSibling){ ???????????if(n.nodeType === 1 && n !== el){ ???????????????n.innerHTML = value; //赋值提示信息 ???????????} ???????} ???}; ???????/** 清空提示 ????* @param el 清空提示的DOM元素 ????*/ ???ValCheck.prototype.clearTip = function(el){ ???????var cls = ‘el_error‘; ???????var reg = new RegExp(‘(\\s|^)‘ + cls + ‘(\\s|$)‘); ???????el.className.replace(reg,‘‘); ???????}; ???????/****************对外开放方法******************/ ???????/** 外部可调用click方法,比如点击事件时候调用checkFun.click(),验证成功返回true ????* @param formId 验证DOM为formId区域下的表单 ????* @result {boolen} true or false ????* */ ???checkFun.click = function(formId){ ???????formId = formId || opts.formId; ???????var resultObj = []; //存放需要验证的DOM对象 ???????var rangeobj = document.getElementById(formId); ???????if(rangeobj.getElementsByClassName){ ???????????rangeobj = [].slice.apply(rangeobj.getElementsByClassName(ValCheck.defaults.checkClass)); ???????}else{ ???????????var tags = rangeobj.getElementsByTagName("*"); ?????????????//遍历每个DOM元素 ???????????for(var i = 0, len = tags.length; i < len; i++){ ???????????????// 获取到当前遍历元素所使用的所有类名 ?????????????????var classNames = tags[i].className.split(" "); ?????????????????for(var j = 0, l=classNames.length; j < l; j++){ ???????????????????if(classNames[j] == ValCheck.defaults.checkClass){ ???????????????????????rangeobj.push(tags[i]); ???????????????????????break; ???????????????????} ???????????????} ???????????} ???????} ???????var check = new ValCheck(); ???????var checkResultNumber = 0; //检测结果,检查通过的数目 ???????var resultState = true; ???????//开始验证所有DOM元素 ???????for(var domNumber = 0, domlen = rangeobj.length; domNumber < domlen; domNumber++){ ???????????everyResultState = check.formValidator(rangeobj[domNumber]); ???????????if(resultState){ ???????????????checkResultNumber ++; ???????????} ???????} ???????if(checkResultNumber !== domlen ){ ???????????resultState = fasle; ???????} ???????return resultState; ???}; ???????/** 判断密码强度 ????* @param val 当前DOM元素的value值 ????* @return {number} 返回数字等级 ????* */ ???checkFun.pwdStrong = function(val){ ???????var lv=0; ???????if(val.match(/[a-z]/g)){lv++;} ???????if(val.match(/[A-Z]/g)){lv++;} ???????if(val.match(/[0-9]/g)){lv++;} ???????if(val.match(/(.[^a-z0-9A-Z])/g)){lv++;} ???????????if(lv > 4){lv=4;} ???????if(lv===0) return false; ???????return lv; ???} ???????window.checkFun = checkFun;})();
css代码:
.same{margin-bottom: 30px;position:relative;}.same input{border:1px solid #ccc;width:200px;height:30px;line-height: 30px;padding-left:10px;}.valid{color:red;position:absolute;}.submitBtn{cursor: pointer;}
html代码:
<div id="verifyCheck"> ???<div class="same"> ???????<input type="text" placeholder="邮箱" value="" class="required email" id="email" data-valid="isNonEmpty||isEmail" data-error="email不能为空||邮箱格式不正确"/> ???????<label class="focus valid"></label> ???</div> ???<div class="same"> ???????<input type="password" placeholder="密码" value="" class="required password" id="password" data-valid="isNonEmpty||between:3-5" data-error="密码不能为空||密码长度在3-5位"/> ???????<label class="focus valid"></label> ???</div> ???<div class="same"> ???????<input type="password" placeholder="重复密码" value="" class="required password2" id="password2" data-valid="isNonEmpty||isRepeat:password" data-error="密码不能为空||两次输入的密码不一致"/> ???????<label class="focus valid"></label> ???</div> ???<button class="submitBtn" id="submitBtn">提交</button></div>
JS调用:
checkFun({ ???????onBlur:function(el,state){ ???????????console.log($(el)); ???????} ??}); ????document.getElementById(‘submitBtn‘).addEventListener(‘click‘,function(){ ????????checkFun.click(); ?},false)
[代码笔记]原生JS实现验证框架 checkFun(待优化)
原文地址:https://www.cnblogs.com/moqiutao/p/7977259.html