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 解析json的代码
Dec 16 Javascript
jQuery获取样式中的背景颜色属性值/颜色值
Dec 17 Javascript
JavaScript伸缩的菜单简单示例
Dec 03 Javascript
JavaScript如何调试有哪些建议和技巧附五款有用的调试工具
Oct 28 Javascript
跟我学习javascript的浮点数精度
Nov 16 Javascript
修改jquery中dialog的title属性方法(推荐)
Aug 26 Javascript
D3.js实现散点图和气泡图的方法详解
Sep 21 Javascript
AngularJS监听路由的变化示例代码
Sep 23 Javascript
JavaScript 继承详解(五)
Oct 11 Javascript
ES2015 Symbol 一种绝不重复的值
Dec 25 Javascript
vue.js学习笔记:如何加载本地json文件
Jan 17 Javascript
Vue打包部署到Nginx时,css样式不生效的解决方式
Aug 03 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 radio 单选框获取与保持值的实现代码
2010/05/15 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
2016/04/11 PHP
功能强大的php文件上传类
2016/08/29 PHP
解决微信授权回调页面域名只能设置一个的问题
2016/12/11 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
扩展JS Date对象时间格式化功能的小例子
2013/12/02 Javascript
javascript实现瀑布流自适应遇到的问题及解决方案
2015/01/28 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
2015/08/08 Javascript
jQuery Real Person验证码插件防止表单自动提交
2015/11/06 Javascript
js老生常谈之this,constructor ,prototype全面解析
2016/04/05 Javascript
BootStrap Progressbar 实现大文件上传的进度条的实例代码
2016/06/27 Javascript
jquery 多个radio的click事件实例
2016/12/03 Javascript
Node.js读取文件内容示例
2017/03/07 Javascript
vue省市区三联动下拉选择组件的实现
2017/04/28 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
浅谈angular4生命周期钩子
2017/09/05 Javascript
利用js将ajax获取到的后台数据动态加载至网页中的方法
2018/08/08 Javascript
JavaScript 九种跨域方式实现原理
2019/02/11 Javascript
js实现淘宝首页的banner栏效果
2019/11/26 Javascript
Vue切换Tab动态渲染组件的操作
2020/09/21 Javascript
[45:52]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第二场 12.09
2020/12/12 DOTA
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
CSS3模拟动画下拉菜单效果
2017/04/12 HTML / CSS
Perricone MD裴礼康美国官网:抗衰老护肤品
2016/09/26 全球购物
美国第二大连锁书店:Books-A-Million
2017/12/28 全球购物
加拿大休闲和工业服装和鞋类零售商:L’Équipeur
2018/01/12 全球购物
应届生煤化工求职信
2013/10/21 职场文书
初中地理教学反思
2014/01/11 职场文书
高中地理教学反思
2014/01/29 职场文书
小学英语课后反思
2014/04/26 职场文书
黄山导游词
2015/01/31 职场文书
刑事上诉状(无罪)
2015/05/23 职场文书
汉语拼音教学反思
2016/02/22 职场文书
遇事可以测出您的见识与格局
2019/09/16 职场文书
Win11局域网共享权限在哪里设置? Win11高级共享的设置技巧
2022/04/05 数码科技