这篇文章发布于 2019年08月18日,星期日,23:03,归类于 JS API。 阅读 40828 次, 今日 9 次 9 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8895
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、先从form内置验证的外部表现说起
说起form内置验证,很多人想到的是设置required
这样的HTML属性,然后表单提交的时候出现这样的提示效果:
实际上,这只是表象,只是form表单原生验证的一小部分。form内置验证的精髓其实不止这点表面的东西。
例如CSS侧有诸多匹配的伪类,如:required
伪类, :optional
伪类或是:valid
,:invalid
伪类等。
又例如JS DOM事件这块表单元素可以监听'invalid'
和'valid'
事件。
又例如JS DOM API这一块则有诸多内置的验证方法和属性,这就是本文要介绍的知识点。
二、form表单元素内置验证方法和属性
开门见山不打弯,共3个方法和1个属性。
3个方法分别是checkValidity()
, reportValidity()
, setCustomValidity()
方法,1个属性是validity
属性。
具体如下:
checkValidity()方法
checkValidity()
方法可以用来验证当前表单控件元素,或者整个表单是否验证通过,返回值是布尔值,true
或者false
。
例如,某下拉框元素是否验证通过:
var isSelectPassing = document.querySelector('select').checkValidity(); // true或false
或者整个表单元素是否验证通过:
var isFormPassing = document.forms[0].checkValidity(); // true或false
reportValidity()方法
reportValidity()
方法可以触发浏览器的内置的验证提示交互,返回布尔值,true
或者false
。例如:
document.querySelector('select').reportValidity()
会触发下拉框的错误提示,如下图所示:
另外,reportValidity()
方法IE浏览器并不支持,Edge 17+开始支持。
setCustomValidity()方法
顾名思义就是设置自定义的验证,我们可以使用这个方法自定义提示文字。
语法如下:
ele.setCustomValidity(str);
其中,str
为字符串,表示出错提示的文字信息,如果是空字符串,则表示不使用自定义的错误提示。
例如上面的reportValidity()
方法的下拉出错提示是“请在列表中选择一项”。
如果我们希望改成“请选择城市”,则可以下面这样:
var eleSelect = document.querySelector('select'); if (eleSelect.validity.valueMissing == true) { eleSelect.setCustomValidity('请选择城市'); } eleSelect.reportValidity();
此时,提示效果就是:
validity属性与ValidityState对象
每一个标准的表单控件,例如输入框,下拉框以及单复选框都内置一个validity
属性,这是个只读属性,可以返回当前元素各种验证状态,例如:
console.dir(document.querySelector('select').validity);
在Chrome浏览器下返回的结果是一个ValidityState对象,包含的属性和属性值如下:
badInput: false customError: false patternMismatch: false rangeOverflow: false rangeUnderflow: false stepMismatch: false tooLong: false tooShort: false typeMismatch: false valid: false valueMissing: true
控制台输出截图如下:
其中
- badInput
- 只读。属性值为布尔类型。输入框里面的值浏览器没办法进行转换。例如
'number'
类型输入框里面是中文字符(MDN上说法,但是自己测试无法复现),此时值是true
。此属性IE浏览器并不支持。此属性建议了解即可。 - customError
- 只读。属性值为布尔类型。如果元素调用
setCustomValidity()
方法设置了自定义的验证信息则值是true
。 - patternMismatch
- 只读。属性值为布尔类型。和指定的
pattern
正则属性值不匹配的时候值是true
。会匹配:invalid
这个CSS伪类。 - rangeOverflow
- 只读。属性值为布尔类型。超过
max
属性设置的值的时候会是true
。同时会匹配CSS:invalid
和:out-of-range
伪类。 - rangeUnderflow
- 只读。属性值为布尔类型。小于
min
属性设置的值的时候会是true
。同时会匹配CSS:invalid
和:out-of-range
伪类。 - stepMismatch
- 只读。属性值为布尔类型。输入框当前值和
step
属性值不匹配的时候stepMismatch
的值会是true
。同时元素会匹配CSS:invalid
和:out-of-range
伪类。 - tooLong
- 只读。属性值为布尔类型。输入内容长度超出
maxlength
的限制时候会是true
。同时会匹配CSS:invalid
和:out-of-range
伪类。 - tooShort
- 只读。属性值为布尔类型。输入内容长度不足
minlength
的限制时候会是true
。同时会匹配CSS:invalid
和:out-of-range
伪类。此属性IE浏览器并不支持,因为不支持minlength
属性。 - typeMismatch
- 只读。属性值为布尔类型。输入框的值和输入框类型不匹配的时候该属性值会是
true
。例如输入框type类型是email或者url时候。如果值是true
,会匹配:invalid
这个CSS伪类。 - valid
- 只读。属性值为布尔类型。当前元素是否完全验证通过,通过是
true
,会匹配:valid
这个CSS伪类;不通过是false
,会匹配:invalid
这个CSS伪类。 - valueMissing
- 只读。属性值为布尔类型。如果元素设置了
required
属性,同时输入框的值为空,则该属性值是true
。如果值是true
,会匹配:invalid
这个CSS伪类。
补充于2021-07-30
validationMessage属性
语法如下:
var message = ele.validationMessage;
表示,当前输入框元素如果要显示出错提示,出错提示的文字内容是什么。
例如一个普通的输入框:
<input id="input">
input.validationMessage
的返回值是空字符串''
。
如果输入框设置了required属性:
<input id="input" required>
则input.validationMessage
的返回值是:’请填写此字段。’
如果输入框设置了pattern
属性,同时输入框里面的值格式不符:
<input id="input" required pattern="^\d{6}$">
则input.validationMessage
的返回值是:’请与所请求的格式保持一致。’
以及其他一些常见就不举例了,运行结果示意如下截图:
willValidate属性
语法如下:
var result = ele.willValidate;
表示元素能够被验证。
输入框元素都是true
,但是如果输入框是disabled
禁用的,则result
是false
。
这里这张测试结果示意图:
三、IE9浏览器的polyfill
以上所有原生的表单验证方法和属性IE9浏览器都不支持,IE10+浏览器都支持。
如果想要IE9浏览器也支持,需要写个polyfill,我大概搜索了下,checkValidity()
等几个方法并没有合适的polyfill,已有的一些项目为了兼容IE8,更像是shim,没有专门为IE9打造了polyfill。
倒是validity属性找到个看上去有些靠谱的polyfill。您可以狠狠地点击这里(可以右键→另存为):validity-polyfill.js。这个polyfill出自这里,不过我并没有仔细验证过其正确性。
之后我会自己针对IE9浏览器吧checkValidity()
等几个方法给补上。
四、写着写着就成了文档
本文下笔之处还以为会发现一些好玩的东西,例如自定义表单验证逻辑,后来发现自己想多了,setCustomValidity()
方法并没有自己预想的那么强大,就是个改变提示文字信息的方法。
整理来整理去,最后就成了一个比较详尽的关于表单原生验证的文档了。
之后写验证组件,我会借助这些原生的已经内置好的验证方法来实现,可以省去不少功夫,会很有意思。
日后的精彩演绎源自平时平淡的积累。
对于大部分的人,对于本文这些API是无感的,想不到如何在实际项目中应用,觉得很鸡肋,实际上大有可为的,我已经想要跃跃欲试了,嘿嘿。
本文为原创文章,欢迎分享,勿全文转载,如果内容你实在喜欢,可以加入收藏夹,永不过期,而且还会及时更新知识点以及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=8895
(本篇完)
- CSS蛋疼应用之:数据上报和HTML验证 (0.670)
- CSS3 box-shadow兼容loading效果兼IE10+ CSS Hack介绍 (0.298)
- 小tip: CSS动态实现文本框清除按钮的隐藏与显示 (0.223)
- CSS :default伪类选择器简介 (0.186)
- 完善:HTML5表单新特征简介与举例 (0.112)
- HTML5 Boolean类型属性(如required)值的JS获取 (0.112)
- 如何让文字作为CSS背景图片显示? (0.112)
- 原来DOM还有toggleAttribute这样的JS API (0.112)
- HTML5新增的form属性简介 (0.033)
- HTML input type=file文件选择表单元素二三事 (0.033)
- 2022年新出了哪些form表单新特性? (RANDOM - 0.033)
如果页面里100个表单元素,提交的时候,调用 form[0].checkValidity ,但是这个整体返回 true 或者 false,那如何知道是哪一个元素 required 的时候出了问题导致整体没通过呢
可能需要遍历元素才行
棒,这样不用 UI 库的表单验证方法了
能静下心来把原生api研究的如此透彻,真的很厉害?
见过这种样式的表单验证提示,当时以为是插件实现的样式,现在才知道原来是原生的。
挺好的,我之前尝试用原生校验用在项目上,结果在firefox上,会有红色边框(Firefox特意添加的),结果被产品dist了。
哈哈,上周做的基于checkValidity验证做的表单组件
https://xy-ui.codelabo.cn/docs/#/xy-form?id=%e4%ba%a4%e4%ba%92%e5%ae%9e%e4%be%8b
除了 validity 之外,还有两个属性:
1. validationMessage
2. willValidate
前排, mark