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 相关文章推荐
jquery1.83 之前所有与异步列队相关的模块详细介绍
Nov 13 Javascript
JS中prototype关键字的功能介绍及使用示例
Jul 21 Javascript
15款jQuery分布引导插件分享
Feb 04 Javascript
javascript中checkbox使用方法实例演示
Nov 19 Javascript
jquery zTree异步加载简单实例讲解
Feb 25 Javascript
jQuery代码实现表格中点击相应行变色功能
May 09 Javascript
jquery输入数字随机抽奖特效的简单实现代码
Jun 10 Javascript
Javascript OOP之面向对象
Jul 31 Javascript
JS实现table表格固定表头且表头随横向滚动而滚动
Oct 26 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
Jan 25 Javascript
基于vue实现可搜索下拉框定制组件
Mar 26 Javascript
Vue实现简单计算器
Jan 20 Vue.js
使用开源工具制作网页验证码的方法
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知识收集
2012/08/20 PHP
thinkphp中连接oracle时封装方法无法用的解决办法
2013/06/17 PHP
PHP实现图片自动清理的方法
2015/07/08 PHP
PHP INT类型在内存中占字节详解
2019/07/20 PHP
jquery.ui.draggable中文文档
2009/11/24 Javascript
奉献给JavaScript初学者的编写开发的七个细节
2011/01/11 Javascript
setTimeout的延时为0时多个浏览器的区别
2012/05/23 Javascript
jquery插件tooltipv顶部淡入淡出效果使用示例
2013/12/05 Javascript
Iframe 自动适应页面的高度示例代码
2014/02/26 Javascript
浅析JavaScriptSerializer类的序列化与反序列化
2016/11/22 Javascript
JavaScript使用Ajax上传文件的示例代码
2017/08/10 Javascript
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
Bootstrap-table使用footerFormatter做统计列功能
2018/09/07 Javascript
在element-ui的el-tree组件中用render函数生成el-button的实例代码
2018/11/05 Javascript
vue+webpack中配置ESLint
2018/11/07 Javascript
Vue.js 中的实用工具方法【推荐】
2019/07/04 Javascript
layui实现三级联动效果
2019/07/26 Javascript
js实现查询商品案例
2020/07/22 Javascript
Vue Render函数原理及代码实例解析
2020/07/30 Javascript
Python中map和列表推导效率比较实例分析
2015/06/17 Python
python3 实现的人人影视网站自动签到
2016/06/19 Python
使用Python的package机制如何简化utils包设计详解
2017/12/11 Python
浅谈Python实现贪心算法与活动安排问题
2017/12/19 Python
python画出三角形外接圆和内切圆的方法
2018/01/25 Python
Python可变参数会自动填充前面的默认同名参数实例
2019/11/18 Python
简单了解Python3 bytes和str类型的区别和联系
2019/12/19 Python
pytorch如何冻结某层参数的实现
2020/01/10 Python
美国知名的网上鞋类及相关服装零售商:Shoes.com
2017/05/06 全球购物
乌克兰网上服装店:Bolf.ua
2018/10/30 全球购物
控制工程专业个人求职信
2013/09/25 职场文书
出国签证在职证明
2014/01/16 职场文书
职业女性的职业规划
2014/03/04 职场文书
政风行风整改方案
2014/10/25 职场文书
如何书写授权委托书?
2019/06/25 职场文书
HTML页面滚动时部分内容位置固定不滚动的实现
2021/04/14 HTML / CSS
Python绘制散乱的点构成的图的方法
2022/04/21 Python