js浏览器html5表单验证


Posted in Javascript onOctober 17, 2016

html5表单添加了很多类型的表单,而且还自带验证的功能。在移动端,手机等设备能够根据不同的input类型弹出不同的键盘,例如iphone弹的键盘

js浏览器html5表单验证

但是由于不同的浏览器对不合法输入提示文案不一致,样式也不一样,并且老的浏览器不兼容(IE9及以下),导致了在生产环境中比较少见到。例如对于邮箱格式的检验,不同浏览器的效果如下:

Chrome

js浏览器html5表单验证

Firefox

js浏览器html5表单验证

IE

js浏览器html5表单验证

safari

js浏览器html5表单验证

html5的表单跨浏览器有很大的问题

具体来说存在三个问题:

(1) 输入框blur的时候不会触发检查,只有在点提交时才触发,但是一般是希望用户一旦离开这个输入框就对其输入进行检查

(2) 提示控件的UI差异很大,safari还不会触发提示控件,一些浏览器如IE会给非法的输入框添加一个红色的边框

(3) 文案是写死的,并且不同浏览器的文案不一致,其中应该以Chrome的提示最好

一、跨浏览器的表单验证插件

为解决这些问题,网上有一些插件,如html5 Form,做了跨浏览器的处理,但是使用起来效果并不是十分让人满意,html5 Form在safari下面就失效了。在多方查找和尝试未果之下,笔者自已写了一个跨浏览器的表单检测插件,效果如下:

Chrome

js浏览器html5表单验证

Firefox

js浏览器html5表单验证

IE

js浏览器html5表单验证

safari

js浏览器html5表单验证

插件效果示例:解决跨浏览器问题

1. 统一UI

这个插件解决了上面的问题,首先是统一了UI,模拟了Chrome的提示效果,UI的样式和显示位置都是一致的,并且可以自定义。对于文案问题提供了是否使用浏览器默认文案的选项,因为考虑到有些浏览器如Chrome的提示比较智能,例如上面的邮箱文案,如果不使用则自定义文案。

2. 支持异步验证

另外一个强大的功能是支持异步验证,如验证用户名是否存在:

js浏览器html5表单验证

插件支持异步验证

3. 支持多重类型规则验证

还有,支持不同类型的规则验证,如必填/格式/自定义,例如对电话号码的验证有两个要求,一个是必填,另外一个是符合电话号码的格式:

js浏览器html5表单验证js浏览器html5表单验证

支持不同规则类型的验证

4. 能够中英文切换

还考虑到了双语站中英文切换的问题:

js浏览器html5表单验证js浏览器html5表单验证

支持中英文切换

二、插件使用方法

1. 最简单的使用

插件已经上传到github,里面包含了一个demo,demo的效果如下:

js浏览器html5表单验证

form的html结构:

<form class="sign-up">
 <label>邮箱地址</label>
 <input type="email" name="account" t="email" required="">
 <label>密码</label>
 <input type="password" name="password" pattern=".{6,20}" pm="密码要在6到20位之间" required="">
 <label>确认密码</label>
 <input type="password" name="confirm-pwd">
 <input id="confirm-sign" type="submit" value="注册">
 <p></p>
 </form>

     上面第3行,定义了input的type="email",还要再写多一个t="email"主要是因为IE10以下的浏览器会把不认识的type强制改成text。

     无关的CSS略。有了上面的html结构之后,只需要初始化插件就可以了

new Form($(".sign-up")[0], {
 errorMsgClass: "error", //错误提示框的类名,用于自定义样式
 errorInputClass: "invalid", //input无效的类名,用于自定义样式
}, submit);

function submit(){
 console.log("表单验证成功,准备提交");
 //提交操作 
}

      执行new From的时候传了3个参数,第一个是form的DOM元素,第二个参数是验证规则的一些配置,第三是验证成功的回调函数。对应如下:

var Form = function(form, checkOpt, submitCallback){
 //...
}

第二个参数checkOpt有两个属性errorMsgClass和errorInputClass用来自定义样式。

最简单的初始化,能够实现required属性、pattern属性和类型检验生效。pattern使用正则表达式,其错误提示信息放在pm属性里,如上面的 pm="密码要在6到20位之间" 。

2. 添加自定义检验

上面的密码需要保证两次的输入一致,在checkOpt里面添加自定义验证:

checkOpt.rule = {
 "confirm-pwd": {
 check: checkPwdIdentity, //自定义检验函数
 msg: "两次密码输入不一致" //出错提示信息
 }
 } 
 
 function checkPwdIdentity(){
 if(this.form["password"].value !== this.form["confirm-pwd"].value){
 return false;
 }
 return true;
 }

如上所示,添加了一个rule属性,key值为input的name属性,value值包含一个自定义的检验函数和出错信息

3. 自定义异步检验

有些数据需要向服务请求检验,如检验账户是否存在

checkOpt.rule.account = {
 check: checkAccountExist,
 msg: "账户已存在!",
 async: true //标志位,说明是异步的检验
};

function checkAccountExist(failCallback, successCallback){
 var input = this;
 util.ajax("/register/hasUser", {account: this.value}, function(data){
 //如果用户存在则调用failCallback,让插件添加一个错误提示
 if(data.isUser === true){
 failCallback();
 }
 //成功则调用成功的回调函数
 else{
 successCallback();
 }
 });
 }

在回调函数里面传进两个参数,如果检验失败则执行第一个参数,成功则执行第二个参数,为插件所用。

4. 添加自定义类型出错提示

Form已经提供了一套默认类型出错提示:

Form.prototype.validationMessage_cn = {
 email: '无效的邮箱格式',
 number: '无效的数字格式',
 url: '无效的网址格式',
 password: '格式无效',
 text: '格式无效'
};

      你也可以自定义一个,将上面的文案换掉即可,暂时没有提供参数

      另外可以取消掉浏览器提供的文案,用上面的默认文案

//如果浏览器的语言不是中文的话,就不要使用英文的文案了,双语站时候适用
checkOpt.disableBrowserMsg = !(navigator.language || navigator.userLanguage).match(/cn/i)

      还可以指定Form使用的语言:

//双语站切换时适用
checkOpt.lang = "cn"; //或者en
 

三、插件源码解析

插件的代码并不是很复杂,只是需要考虑很多细节。

1. 为非html5浏览器添加checkValidity函数

如果没有checkValidity函数的话就给它添加一个,核心代码见Github,这里不进行详细说明。

var input = document.createElement("input");
 if(!input.checkValidity){
 HTMLInputElement.prototype.checkValidity = function(){
 //详细代码见github
 }
 }
 

2. 添加错误提示

重点是计算提示显示的位置,

Form.prototype.addErrorMsg = function(input, msg){

}

3. 异步检验的实现

异步检验难点在于,什么时候执行submit回调。解决方案是给每个input添加一个hasCheck属性,如果检查通过则设置为true,一旦focus了就设为false,blur则触发检查。只有所有的input都有了hasCheck为true时才能执行submit回调。下面的checkAsync的第二个参数,点提交时设置成true,而blur验证则为false

Form.prototype.checkAsync = function(input, doesSubmit){
 name = input.name;
 var rule = input.form.Form.checkOpt.rule;
 rule[name]["check"].call(input, 
 //检验失败回调函数
 function(){
 var Form = input.form.Form;
 Form.addErrorMsg(input, Form.checkOpt.rule[name].msg);
 },
 //检验成功回调函数 
 function(){
 input.hasCheck = true;
 if(doesSubmit){
 input.form.Form.tryCallSubmit(input);
 }
 });
};

代码的第14行检查除submit外所有的input是否为hasCheck为true,如果有则执行submit callback。    

 现在这个Form插件只支持text/password/url/email/number这几种input,应该可以满足大部份的表单提交,如果需要,可再继续完善。 

 个人博客:http://yincheng.site/html5-form

参考:

1. Making HTML5 Form backwards compatible

2. Building HTML5 Form Validation Bubble Replacements

3. Github工程

本文已被整理到了《jquery表单验证大全》、《JavaScript表单验证大全》,欢迎大家学习阅读。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用javascript作一个通用向导说明
Aug 30 Javascript
仿微博字符限制效果实现代码
Apr 20 Javascript
JQueryEasyUI Layout布局框架的使用
Apr 08 Javascript
html向js方法传递参数具体实现
Aug 08 Javascript
javascript日期格式化示例分享
Mar 05 Javascript
探寻Javascript执行效率问题
Nov 12 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
Feb 24 Javascript
Bootstrap modal 多弹窗之叠加引起的滚动条遮罩阴影问题
Feb 27 Javascript
JS沙箱模式实例分析
Sep 04 Javascript
纯js实现隔行变色效果
Nov 29 Javascript
vue实现移动端H5数字键盘组件使用详解
Aug 25 Javascript
利用vue3+ts实现管理后台(增删改查)
Oct 30 Javascript
使用开源工具制作网页验证码的方法
Oct 17 #Javascript
jQuery 实现ajax传入参数含有特殊字符的方法总结
Oct 17 #Javascript
JavaScript中的ajax功能的概念和示例详解
Oct 17 #Javascript
JQuery中解决重复动画的方法
Oct 17 #Javascript
bootstrap读书笔记之CSS组件(上)
Oct 17 #Javascript
原生JavaScript制作计算器
Oct 16 #Javascript
JavaScript 实现的checkbox经典实例分享
Oct 16 #Javascript
You might like
PHP基于CURL进行POST数据上传实例
2014/11/10 PHP
PHP实现XML与数据格式进行转换类实例
2015/07/29 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
php设计模式之工厂模式用法经典实例分析
2019/09/20 PHP
JQuery 遮罩层实现(mask)实现代码
2010/01/09 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
JS 实现Base64编码与解码实例详解
2016/11/07 Javascript
Javascript中click与blur事件的顺序详析
2017/04/25 Javascript
详解webpack+express多页站点开发
2017/12/22 Javascript
angularJS的radio实现单项二选一的使用方法
2018/02/28 Javascript
解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题
2018/08/24 Javascript
深入理解Angularjs 脏值检测
2018/10/12 Javascript
微信小程序中使用echarts的实现方法
2019/04/24 Javascript
vue仿淘宝滑动验证码功能(样式模仿)
2019/12/10 Javascript
JavaScript arguments.callee作用及替换方案详解
2020/09/02 Javascript
Vue实现返回顶部按钮实例代码
2020/10/21 Javascript
详解javascript脚本何时会被执行
2021/02/05 Javascript
[07:47]DOTA2国际邀请赛采访专栏:探访Valve总部
2013/08/08 DOTA
[01:01:31]2018DOTA2亚洲邀请赛3月29日小组赛B组 Mineski VS paiN
2018/03/30 DOTA
python搭建虚拟环境的步骤详解
2016/09/27 Python
Python编程给numpy矩阵添加一列方法示例
2017/12/04 Python
PyQt弹出式对话框的常用方法及标准按钮类型
2019/02/27 Python
在python tkinter中Canvas实现进度条显示的方法
2019/06/14 Python
python 画二维、三维点之间的线段实现方法
2019/07/07 Python
Django使用消息提示简单的弹出个对话框实例
2019/11/15 Python
Python+numpy实现矩阵的行列扩展方式
2019/11/29 Python
使用py-spy解决scrapy卡死的问题方法
2020/09/29 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
2021/02/20 Python
JD Sports澳洲官网:英国领先的运动鞋和运动时尚零售商
2020/02/15 全球购物
职业生涯规划书怎么写?
2014/09/14 职场文书
政风行风建设整改方案
2014/10/27 职场文书
三好学生评语大全
2014/12/29 职场文书
研究生毕业登记表的自我鉴定范文
2019/07/15 职场文书
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
《废话连篇——致新手》——chinapizza
2022/04/05 无线电