一、前言

  最近在开发一个新项目,需要做登陆等一系列的表单提交页面。在经过“缜密”的讨论后,我们决定 不用外部流行的框架,如bootstrap,由于我负责的模块

仅仅是其中的一部分,因此少数服从多数,无奈只能抛弃bootstrap等提供的布局,样式以及验证等一些列如此方便的组件,(他们拒绝使用的原因也令人发省)。

  那么问题就来了。

二、设计理念

  我们都知道,在抛开外部框架,仅仅用JS+css+html 去开发一个页面,是很复杂的,尤其是在没有美工,前台的情况下。其实bootstrap 在一定程度上 为公司节省了 美工 前台的开支...

  废话少说,1天搞定了页面之后,开始为表单添加JS验证。用原生JS写验证是一件很吃力的事情,就算把各种验证方式,正则表达式,为空判断,长度判断,复杂各类字符组合判断等,集中到一个文件当中,依然可能无法排除每个页面中各种的条件语句,万一一个表单 N个input呢?

  而jquery validate组件 等  是怎样实现的呢,其实现实中表示,只要会用就行了  不用了解其工作原理。就像你只要会开汽车 就足够了,不用去了解车是怎么实现的,那么当你有一天会开飞机,那么你就登上了人生的“巅峰”。

三、自定义验证器

  废话不多说 直接上代码

  

/*** Created by sicd 2015-5-29.*/
$(function(){
});var suc_img='<i class="error-img"></i>';
var err_tag='<span class="error-msg" id="error-msg" style="display: block;"></span>';function isIP(strIP) {if (isNull(strIP)) return false;var re=/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/g //匹配IP地址的正则表达式if(re.test(strIP)){if( RegExp.$1 <256 && RegExp.$2<256 && RegExp.$3<256 && RegExp.$4<256) return true;}return false;
}/*用途:检查输入字符串是否为空或者全部都是空格输入:str返回:如果全是空返回true,否则返回false*/
function isNull( str ){if ( str == "" ) return true;var regu = "^[ ]+$";var re = new RegExp(regu);return re.test(str);
}/*用途:检查输入对象的值是否符合整数格式输入:str 输入的字符串返回:如果通过验证返回true,否则返回false*/
function isInteger( str ){var regu = /^[-]{0,1}[0-9]{1,}$/;return regu.test(str);
}/*用途:检查输入手机号码是否正确输入:s:字符串返回:如果通过验证返回true,否则返回false*/
function checkMobile( s ){var regu =/^[1][3][0-9]{9}$/;var re = new RegExp(regu);if (re.test(s)) {return true;}else{return false;}
}/*用途:检查输入字符串是否符合正整数格式输入:s:字符串返回:如果通过验证返回true,否则返回false*/
function isNumber( s ){var regu = "^[0-9]+$";var re = new RegExp(regu);if (s.search(re) != -1) {return true;} else {return false;}
}/*用途:检查输入字符串是否是带小数的数字格式,可以是负数输入:s:字符串返回:如果通过验证返回true,否则返回false*/
function isDecimal( str ){if(isInteger(str)) return true;var re = /^[-]{0,1}(\d+)[\.]+(\d+)$/;if (re.test(str)) {if(RegExp.$1==0&&RegExp.$2==0) return false;return true;} else {return false;}
}/*用途:检查输入对象的值是否符合端口号格式输入:str 输入的字符串返回:如果通过验证返回true,否则返回false*/
function isPort( str ){return (isNumber(str) && str<65536);
}/*用途:检查输入对象的值是否符合E-Mail格式输入:str 输入的字符串返回:如果通过验证返回true,否则返回false*/
function isEmail( str ){var myReg = /^[-_A-Za-z0-9]+@([_A-Za-z0-9]+\.)+[A-Za-z0-9]{2,3}$/;if(myReg.test(str)) return true;return false;
}/*用途:检查输入字符串是否符合金额格式格式定义为带小数的正数,小数点后最多三位输入:s:字符串返回:如果通过验证返回true,否则返回false*/
function isMoney( s ){var regu = "^[0-9]+[\.][0-9]{0,3}$";var re = new RegExp(regu);if (re.test(s)) {return true;} else {return false;}
}
/*用途:检查输入字符串是否只由英文字母和数字和下划线组成输入:s:字符串返回:如果通过验证返回true,否则返回false*/
function isNumberOr_Letter( s ){//判断是否是数字或字母var regu = "^[0-9a-zA-Z\_]+$";var re = new RegExp(regu);if (re.test(s)) {return true;}else{return false;}
}
/*用途:检查输入字符串是否只由英文字母和数字组成输入:s:字符串返回:如果通过验证返回true,否则返回false*/
function isNumberOrLetter( s ){//判断是否是数字或字母var regu = "^[0-9a-zA-Z]+$";var re = new RegExp(regu);if (re.test(s)) {return true;}else{return false;}
}
/*用途:检查输入字符串是否只由汉字、字母、数字组成输入:value:字符串返回:如果通过验证返回true,否则返回false*/
function isChinaOrNumbOrLett( s ){//判断是否是汉字、字母、数字组成var regu = "^[0-9a-zA-Z\u4e00-\u9fa5]+$";var re = new RegExp(regu);if (re.test(s)) {return true;}else{return false;}
}/*用途:判断是否是日期输入:date:日期;fmt:日期格式返回:如果通过验证返回true,否则返回false*/
function isDate( date, fmt ) {if (fmt==null) fmt="yyyyMMdd";var yIndex = fmt.indexOf("yyyy");if(yIndex==-1) return false;var year = date.substring(yIndex,yIndex+4);var mIndex = fmt.indexOf("MM");if(mIndex==-1) return false;var month = date.substring(mIndex,mIndex+2);var dIndex = fmt.indexOf("dd");if(dIndex==-1) return false;var day = date.substring(dIndex,dIndex+2);if(!isNumber(year)||year>"2100" || year< "1900") return false;if(!isNumber(month)||month>"12" || month< "01") return false;if(day>getMaxDay(year,month) || day< "01") return false;return true;
}function getMaxDay(year,month) {if(month==4||month==6||month==9||month==11)return "30";if(month==2)if(year%4==0&&year%100!=0 || year%400==0)return "29";elsereturn "28";return "31";
}/*用途:字符1是否以字符串2结束输入:str1:字符串;str2:被包含的字符串返回:如果通过验证返回true,否则返回false*/
function isLastMatch(str1,str2)
{var index = str1.lastIndexOf(str2);if(str1.length==index+str2.length) return true;return false;
}/*用途:字符1是否以字符串2开始输入:str1:字符串;str2:被包含的字符串返回:如果通过验证返回true,否则返回false*/
function isFirstMatch(str1,str2)
{var index = str1.indexOf(str2);if(index==0) return true;return false;
}/*用途:字符1是包含字符串2输入:str1:字符串;str2:被包含的字符串返回:如果通过验证返回true,否则返回false*/
function isMatch(str1,str2)
{var index = str1.indexOf(str2);if(index==-1) return false;return true;
}/*用途:检查输入的起止日期是否正确,规则为两个日期的格式正确,且结束如期>=起始日期输入:startDate:起始日期,字符串endDate:结束如期,字符串返回:如果通过验证返回true,否则返回false*/
function checkTwoDate( startDate,endDate ) {if( !isDate(startDate) ) {alert("起始日期不正确!");return false;} else if( !isDate(endDate) ) {alert("终止日期不正确!");return false;} else if( startDate > endDate ) {alert("起始日期不能大于终止日期!");return false;}return true;
}/*用途:检查输入的Email信箱格式是否正确输入:strEmail:字符串返回:如果通过验证返回true,否则返回false*/
function checkEmail(strEmail) {
//var emailReg = /^[_a-z0-9]+@([_a-z0-9]+\.)+[a-z0-9]{2,3}$/;var emailReg = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;if( emailReg.test(strEmail) ){return true;}else{alert("您输入的Email地址格式不正确!");return false;}
}/*用途:检查输入的电话号码格式是否正确输入:strPhone:字符串返回:如果通过验证返回true,否则返回false*/
function checkPhone( strPhone ) {var phoneRegWithArea = /^[0][1-9]{2,3}-[0-9]{5,10}$/;var phoneRegNoArea = /^[1-9]{1}[0-9]{5,8}$/;var prompt = "您输入的电话号码不正确!"if( strPhone.length > 9 ) {if( phoneRegWithArea.test(strPhone) ){return true;}else{alert( prompt );return false;}}else{if( phoneRegNoArea.test( strPhone ) ){return true;}else{alert( prompt );return false;}}
}/*用途:检查复选框被选中的数目输入:checkboxID:字符串返回:返回该复选框中被选中的数目*/function checkSelect( checkboxID ) {var check = 0;var i=0;if( document.all(checkboxID).length > 0 ) {for(  i=0; i<document.all(checkboxID).length; i++ ) {if( document.all(checkboxID).item( i ).checked  ) {check += 1;}}}else{if( document.all(checkboxID).checked )check = 1;}return check;
}/** * 检查是否是64的倍数*/
function Is64Multi(num){if(num % 64 == 0){return true;}else{return false;}
}function getTotalBytes(varField) {if(varField == null)return -1;var totalCount = 0;for (i = 0; i< varField.value.length; i++) {if (varField.value.charCodeAt(i) > 127)totalCount += 2;elsetotalCount++ ;}return totalCount;
}function getFirstSelectedValue( checkboxID ){var value = null;var i=0;if( document.all(checkboxID).length > 0 ){for(  i=0; i<document.all(checkboxID).length; i++ ){if( document.all(checkboxID).item( i ).checked ){value = document.all(checkboxID).item(i).value;break;}}} else {if( document.all(checkboxID).checked )value = document.all(checkboxID).value;}return value;
}function getFirstSelectedIndex( checkboxID ){var value = -2;var i=0;if( document.all(checkboxID).length > 0 ){for(  i=0; i<document.all(checkboxID).length; i++ ) {if( document.all(checkboxID).item( i ).checked  ) {value = i;break;}}} else {if( document.all(checkboxID).checked )value = -1;}return value;
}function selectAll( checkboxID,status ){if( document.all(checkboxID) == null)return;if( document.all(checkboxID).length > 0 ){for(  i=0; i<document.all(checkboxID).length; i++ ){document.all(checkboxID).item( i ).checked = status;}} else {document.all(checkboxID).checked = status;}
}function selectInverse( checkboxID ) {if( document.all(checkboxID) == null)return;if( document.all(checkboxID).length > 0 ) {for(  i=0; i<document.all(checkboxID).length; i++ ) {document.all(checkboxID).item( i ).checked = !document.all(checkboxID).item( i ).checked;}} else {document.all(checkboxID).checked = !document.all(checkboxID).checked;}
}function checkDate( value ) {if(value=='') return true;if(value.length!=8 || !isNumber(value)) return false;var year = value.substring(0,4);if(year>"2100" || year< "1900")return false;var month = value.substring(4,6);if(month>"12" || month< "01") return false;var day = value.substring(6,8);if(day>getMaxDay(year,month) || day< "01") return false;return true;
}/*用途:检查输入的起止日期是否正确,规则为两个日期的格式正确或都为空且结束日期>=起始日期输入:startDate:起始日期,字符串endDate:  结束日期,字符串返回:如果通过验证返回true,否则返回false*/
function checkPeriod( startDate,endDate ) {if( !checkDate(startDate) ) {alert("起始日期不正确!");return false;} else if( !checkDate(endDate) ) {alert("终止日期不正确!");return false;} else if( startDate > endDate ) {alert("起始日期不能大于终止日期!");return false;}return true;
}/*用途:检查证券代码是否正确输入:secCode:证券代码返回:如果通过验证返回true,否则返回false*/
function checkSecCode( secCode ) {if( secCode.length !=6 ){alert("证券代码长度应该为6位");return false;}if(!isNumber( secCode ) ){alert("证券代码只能包含数字");return false;}return true;
}/****************************************************function:cTrim(sInputString,iType)description:字符串去空格的函数parameters:iType:1=去掉字符串左边的空格2=去掉字符串左边的空格0=去掉字符串左边和右边的空格return value:去掉空格的字符串****************************************************/
function cTrim(sInputString,iType) {var sTmpStr = ' ';var i = -1;if (iType == 0 || iType == 1) {while (sTmpStr == ' ') {++i;sTmpStr = sInputString.substr(i, 1);}sInputString = sInputString.substring(i);}if (iType == 0 || iType == 2) {sTmpStr = ' ';i = sInputString.length;while (sTmpStr == ' ') {--i;sTmpStr = sInputString.substr(i, 1);}sInputString = sInputString.substring(0, i + 1);}return sInputString;
}
function checkLength (str, lessLen, moreLen) {var strLen = this.length(str);if (lessLen != "") {if (strLen < lessLen)return false;}
}/*描述对字段验证的类*/
function Field(params){this.field_id=params.fid;     //要验证的字段的IDthis.validators=params.val;   //验证器对象数组this.on_suc=params.suc;       //当验证成功的时候执行的事件this.on_error=params.err;     //当验证失败的时候执行的事件this.checked=false;           //是否通过验证
}/*扩展这个类,加入validate方法*/
Field.prototype.validate=function(){//循环每一个验证器for ( var item=0;item<this.validators.length;item++ ){/*for(item in this.valid{ators)*///给验证器附加验证成功和验证失败的回调事件this.set_callback(this.validators[item]);//执行验证器上的Validate方法,验证是否符合规则if(this.validators[item]){if(!this.validators[item].validate(this.data())){break; //一旦任意一个验证器失败就停止}}}
};
//获取字段值的方法
Field.prototype.data=function(){return document.getElementById(this.field_id).value;
};//获取该字段的对象
Field.prototype.obj=function(){return document.getElementById(this.field_id);
}
/*设置验证器回调函数的方法set_callback如下:*/
Field.prototype.set_callback=function(val){var self=this;              //换一个名字来存储this,不然函数的闭包中会覆盖这个名字if(val){val.on_suc=function(){      //验证成功执行的方法self.checked=true;      //将字段设置为验证成功/*self.on_suc(val.tips);  //执行验证成功的事件*///不执行回调$(self.obj()).attr('class','validate-suc');$(self.obj()).nextAll('.error-img').show();$(self.obj()).nextAll('.error-msg').hide().text(val.tips);};val.on_error=function(){    //验证失败的时候执行的方法self.checked=false;     //字段设置为验证失败/*self.on_error(val.tips);//执行验证失败的事件*///不执行回调$(self.obj()).attr('class','validate-err');$(self.obj()).nextAll('.error-img').hide();$('.error-msg').hide();$(self.obj()).nextAll('.error-msg').css('display','inline').text(val.tips);}}
};
/*验证器*///非空验证
function Null_val(tip){this.tips = tip;this.on_suc=null;this.on_error=null;
}
Null_val.prototype.validate=function(fd){if(isNull(fd)){this.on_error();return false;}this.on_suc();return true;
}//长度验证
function Len_val(min_l,max_l,tip){this.min_v=min_l;this.max_v=max_l;this.tips=tip;this.on_suc=null;this.on_error=null;
}
Len_val.prototype.validate=function(fd){if(fd.length<this.min_v||fd.length>this.max_v){this.on_error();return false;}this.on_suc();return true;
}//正整数数字验证
function PosiInteg_val(tip){this.tips=tip;this.on_suc=null;this.on_error=null;
}
PosiInteg_val.prototype.validate = function(fd){if(!isNumber(fd)){this.on_error();return false;}this.on_suc();return true;
}//是否是64的倍数
function Is64Multiple(tip){this.tips=tip;this.on_suc=null;this.on_error=null;
}
Is64Multiple.prototype.validate = function(fd){if(!Is64Multi(fd)){this.on_error();return false;}this.on_suc();return true;
}//select是否选择验证
Select_isSelected.prototype.validate=function(fd){if(fd == -1){this.on_error();return false;}this.on_suc();return true;
}
function Select_isSelected(tip){this.tips=tip;this.on_suc=null;this.on_error=null;
}//正则表达式验证器
function Exp_val(expresion,tip){this.exps=expresion;this.tips=tip;this.on_suc=null;this.on_error=null;
}
Exp_val.prototype.validate=function(fd){if(!fd){this.on_suc();return true;}if(this.exps.test(fd)){this.on_suc();return true;}else{this.on_error();return false;}
}
//远程验证器
function Remote_val(url,tip){this.p_url=url;this.tips=tip;this.on_suc=null;this.on_error=null;
}
Remote_val.prototype.validate=function(fd){var self=this;$.post(this.p_url,{f:fd},function(data){if(data.rs){self.on_suc();return;}else{self.on_error();}},"json");return false;
}
//自定义函数验证器
function Man_val(tip,func){this.tips=tip;this.val_func=func;this.on_suc=null;this.on_error=null;
}
Man_val.prototype.validate=function(fd){if(this.val_func(fd)){this.on_suc();}else{this.on_error();}
}function  FieldForm(items){this.f_item=items;                             //把字段验证对象数组复制给属性for(idx=0;idx<this.f_item.length;idx++){       //循环数组var fc=this.get_check(this.f_item[idx]);   //获取封装后的回调事件$("#"+this.f_item[idx].field_id).change(fc); //绑定到控件上}
};
//绑定验证事件的处理器,为了避开循环对闭包的影响
FieldForm.prototype.get_check=function(v){return function(){   //返回包装了调用validate方法的事件v.validate();}
}
/*绑定按钮click*/
FieldForm.prototype.set_submit=function(bid,bind){var self=this;$("#"+bid).click(function(){if(self.validate()){bind();}});
}
/*这里提到了一个FieldForm的validate方法*/
FieldForm.prototype.validate=function(){for(idx in this.f_item){             //循环每一个验证器this.f_item[idx].validate();     //再检测一遍if(!this.f_item[idx].checked){return false;                //如果错误就返回失败,阻止提交}}return true;                         //一个都没错就返回成功执行提交
}//绑定输入框foucs事件 检测
$(function(){$('.theme-normal input').bind('click', function() {if($(this).hasClass('validate-err')){$('.error-msg').hide();$(this).nextAll('.error-msg').css('display','inline');}});
});

  原理就不多说了,或多或少都有注释,结构就是很简单,最上面一部分是验证方法集合,本人偷懒 直接写在一个文件里,中间部分就是验证器,关于事件触发,回调,定义等,

稍微花点时间就能够看懂。当然 本验证器 还有很多优化的地方,可以通过调整,改变成符合自己的专用验证器。

  下面是调用,或者说是赋予标签 验证器:

  

var form;$(function() {//表单验证var uf = new FieldForm([new Field({fid : "captcha",val : [ new Null_val("验证码为必填项,请输入")]}),new Field({fid : "username",val : [ new Null_val("用户名为必填项,请输入"),new Len_val(1,8,"用户名长度不能超过8位,请重新输入!")]}),new Field({fid : "password",val : [ new Null_val("密码为必填项,请输入"),new Len_val(1,32,"密码长度不能超过32位,请重新输入!")]})
]);uf.set_submit("subBtn", function(form) {$('#subBtn').parents('form').submit();});});

  效果

  

  其中样式 是我自己写的,当input(包括下拉框) 值 发生变化 则进行验证(可以调整验证器,改变触发形式),提交触发验证,input获得焦点时

如果之前验证不通过,则弹出提示框。

四、总结

  很简单,一下午就能看懂 并且调整自如,由于本人懒,没有展示CSS相关的代码文件,如有兴趣,可以吧这些东西提取出来或者做整合

做成组件,做成像日期控件那样的,方便移植和运用。

  

tip:(提示框等样式如果需要可以留言)

转载于:https://www.cnblogs.com/sicd/p/4613628.html

原生JS 表单提交验证器相关推荐

  1. Angualr6表单提交验证并跳转

    在Angular6中,使用NG-ZRROR作为前端开发框架,在进行表单开发时遇到了一些问题,最后解决了,在此记录. 1.表单构造: 引入forms: import { FormGroup, FormB ...

  2. js表单提交,面向对象

    一.js表单验证之后再提交 1.普通按钮onclick函数调用表单的submit()函数 <input type=button name="submit1" value=&q ...

  3. js表单提交 php,JavaScript提交表单的几种方法

    在我们工作中我们会经常使用到form表单,相信大家再熟悉不过了,那么提交表单有很多种方法,JavaScript提交表单的方法又是如何呢,今天就带大家介绍下JavaScript提交表单的几种方法! 第一 ...

  4. 【微信小程序】表单提交验证及获取表单输入的值

    效果图: 说明:请选择房屋所在城市的效果是省市区选择器,刚开始我们可能直接在picker选择器中直接包含一个input输入框实现,但是这样的话点击选择的话可能聚焦在输入框中,我们想要的效果是点击的时候 ...

  5. 表单提交验证新实践之class-validator

    class-validator实践篇 之前有一篇关于class-validator的基础的介绍,这篇来一下如何实践: 首先介绍一下业务背景:简单来说就是一个表单提交 ,根据类型的选择进行四种提交模式. ...

  6. CodeIgniter典型的表单提交验证代码

    view内容: <?php echo form_open('user/reg'); ?><h5>用户名</h5><input type="text& ...

  7. js表单提交无反应的问题

    首先上代码 这个jsp文件是根据用户选择的select值将表单提交给相应的页面进行处理 test6-4-表单.jsp <%@page contentType="text/html;ch ...

  8. html button 自动提交,html+js表单form验证自动提交的2种提交方式button和

    站长设计网页时用到大量的js代码,当然少不了js验证用户输入的合不合格式,格式对就通过验证,自动提交表单,格式不对就弹出错误对话框,重新输入表单.这种判断并提交表单的方法有2种: 1.submit验证 ...

  9. 原生js —— 表单验证练习(12306注册)

    12306注册 知识点: ① 获取父元素:对象.parentElement.对象.parentNode ② 获取最后一个子元素:对象.lastElementChild.对象.lastChild ③ 获 ...

最新文章

  1. Python基础07-数据类型:字典dict
  2. RDKit | 可视化分子来自于xyz文件
  3. Android开发之WebView加载html数据去除Webview滚动条的方法
  4. 【C++基础学习】关于C++静态成员函数和变量
  5. uart串口通信_听说UART与STM32的HAL库更配哦
  6. 美国最受欢迎的电商网站,竟然是一家中国公司?
  7. 成为软件咨询师的关键
  8. 设置ListCtrl列表控件其中某一行的字体和背景颜色
  9. 栈(操作受限的线性表)---C语言版
  10. 用Python在word的指定位置插入图片(使用Python-docx包)
  11. 抖音一起看显示服务器维护中,抖音一起看会看到别的吗?一起看视频期间无法操作是什么意思...
  12. 轻松升级各路硬件,简约时尚的大容量机箱,TT挑战者H6上手
  13. 该网页无法正常运作xxxx将您重定向的次数过多
  14. 捉奸游戏之后,中年危机游戏也来了。。
  15. iPhone支持杜比的机型
  16. 惊闻苏州GDP总量突破2万亿大关!
  17. python crash coures python编程从入门到实践 笔记1 python常见函数
  18. windows格式转换命令convert详解
  19. FPM(FastCGI Process Manager)
  20. ai绘画,初级召唤师教程

热门文章

  1. 阿里P5-基础知识4
  2. 一招搞定GitHub下载加速!
  3. 外设驱动库开发笔记17:MS5803压力变送器驱动
  4. Astyle使用方法
  5. Resuming debugger: error during debugging loop: TypeError: firstViewRangeElement is null
  6. matlab中求分段函数的分段点,matlab求解分段函数问题是如何用下面的算法求解下面的分段函数 爱问知识人...
  7. 同城外卖跑腿系统源码分析
  8. [CSS]CSS 的背景
  9. 物联网开发之智慧农业解决方案
  10. 算法工程师 -常见面试题