赞
踩
对于这个由三部分组成的系列有关HTML5 Web表单的最后一篇文章,我们将讨论JavaScript集成和约束验证API。 如果您尚未这样做,请阅读The Markup和CSS文章,以确保您熟悉这些概念。
HTML5允许我们无需任何JavaScript编码即可实现客户端表单验证。 但是,在实现更复杂的表单时,我们需要增强本机验证,因为:
:invalid
和:required
样式将在用户与表单进行交互之前应用于页面加载。 大量的JavaScript魔术和Constraint Validation API可以改善用户体验。 请注意,如果您想支持我们将竭尽所能的各种浏览器和输入类型,可能会有些混乱。
在HTML5之前,客户端验证涉及在表单上附加一个submit
处理程序,该处理程序将验证字段,显示错误并防止Submit事件。
在HTML5中,浏览器将首先执行自己的验证-在表单有效之前,将不会触发submit
事件。 因此,如果您想做一些复杂的事情,例如显示自己的错误,比较或自动填充字段,则必须通过将表单的noValidate
属性设置为true来关闭本机验证:
- var form = document.getElementById("myform");
- form.noValidate = true;
-
- // set handler to validate the form
- // onsubmit used for easier cross-browser compatibility
- form.onsubmit = validateForm;
当然,这意味着您必须检查代码中的字段错误,但是仍然可以利用本机浏览器验证,我们将在不久后看到。
每个输入字段都有一个.willValidate
属性。 返回:
由于我们在上面禁用了本机验证,因此每个字段都将返回false。 让我们创建一个validateForm
处理程序,该处理程序遍历所有字段并检查本地验证是否可用:
- function validateForm(event) {
-
- // fetch cross-browser event object and form node
- event = (event ? event : window.event);
- var
- form = (event.target ? event.target : event.srcElement),
- f, field, formvalid = true;
-
- // loop all fields
- for (f = 0; f < form.elements; f++) {
-
- // get field
- field = form.elements[f];
-
- // ignore buttons, fieldsets, etc.
- if (field.nodeName !== "INPUT" && field.nodeName !== "TEXTAREA" && field.nodeName !== "SELECT") continue;
循环遍历表单的elements
集合中的所有字段,并检查它们是否是输入,而不是其他类型(例如按钮和字段集)。 下一行很重要…
- // is native browser validation available?
- if (typeof field.willValidate !== "undefined") {
-
- // native validation available
-
- }
- else {
-
- // native validation not available
-
- }
false和undefined都是falsey值,因此您不能仅检查field.willValidate
!
现在我们知道第一个块中的代码将评估何时可以使用本机验证。 然而…
如果阅读了第一部分 ,您会记得不支持的输入类型会回到text
。 例如:
<input type="date" name="dob" />
Firefox 29或IE11本身不支持。 这些浏览器将(有效)呈现:
<input type="text" name="dob" />
但是两种浏览器都支持text
类型的验证,因此field.willValidate
不会返回undefined ! 因此,我们必须检查我们的type
属性是否与对象的.type
属性匹配-如果不匹配,则需要实施旧版后备验证,例如
- // native validation available
- if (field.nodeName === "INPUT" && field.type !== field.getAttribute("type")) {
-
- // input type not supported! Use legacy JavaScript validation
-
- }
如果可以使用本机验证,则可以执行.checkValidity()
方法来验证该字段。 如果没有问题,则该方法返回true,否则返回false 。
有一个类似的.reportValidity()
方法,它无需重新检查即可返回当前状态,尽管这种方法用处不大,并非所有浏览器都支持。
两种方法还将:
.validity
对象,以便可以更详细地检查错误,并且 invalid
事件。 这可用于显示错误,更改颜色等。请注意,没有相应的valid
事件,因此请记住在必要时重置错误样式和消息。 .validity
对象具有以下属性:
.valid
–如果该字段没有错误,则返回true,否则返回false 。
.valueMissing
–如果需要该字段但已输入值,则返回true 。
.typeMismatch
–如果值的语法不正确(例如,格式错误的电子邮件地址),则返回true 。
.patternMismatch
–如果该值与pattern
属性的正则表达式不匹配,则返回true 。
.tooLong
如果该值大于允许的maxlength
则返回true 。
.tooShort
-如果该值大于允许短返回true minlength
。
.rangeUnderFlow
–如果该值小于min
则返回true 。
.rangeOverflow
–如果该值大于max
则返回true 。
.stepMismatch
–如果该值与step
不匹配,则返回true 。
.badInput
–如果条目无法转换为值,则返回true 。
.customError
–如果该字段设置了自定义错误,则返回true 。
并非所有浏览器都支持所有属性,因此请注意不要做太多假设。 在大多数情况下, .valid
或.checkValidity()
的结果应足以显示或隐藏错误消息。
您可以在旧版浏览器中手动模拟.validity
对象,例如
- // native validation not available
- field.validity = field.validity || {};
-
- // set to result of validation function
- field.validity.valid = LegacyValidation(field);
这样可以确保可以在所有浏览器中测试.validity.valid
。
可以传递.setCustomValidity()
方法:
.checkValidity()
字段设置为有效,因此.checkValidity()
和.validity.valid
将返回true ,或者 .checkValidity()
和.validity.valid
将返回false,并且将触发invalid
事件。 请注意,您还可以使用字段的.validationMessage
属性检查当前消息。
现在,我们有了一个简单的通用跨浏览器表单验证系统的基础:
- var form = document.getElementById("myform");
- form.noValidate = true;
-
- // set handler to validate the form
- // onsubmit used for easier cross-browser compatibility
- form.onsubmit = validateForm;
-
- function validateForm(event) {
-
- // fetch cross-browser event object and form node
- event = (event ? event : window.event);
- var
- form = (event.target ? event.target : event.srcElement),
- f, field, formvalid = true;
-
- // loop all fields
- for (f = 0; f < form.elements; f++) {
-
- // get field
- field = form.elements[f];
-
- // ignore buttons, fieldsets, etc.
- if (field.nodeName !== "INPUT" && field.nodeName !== "TEXTAREA" && field.nodeName !== "SELECT") continue;
-
- // is native browser validation available?
- if (typeof field.willValidate !== "undefined") {
-
- // native validation available
- if (field.nodeName === "INPUT" && field.type !== field.getAttribute("type")) {
-
- // input type not supported! Use legacy JavaScript validation
- field.setCustomValidity(LegacyValidation(field) ? "" : "error");
-
- }
-
- // native browser check
- field.checkValidity();
-
- }
- else {
-
- // native validation not available
- field.validity = field.validity || {};
-
- // set to result of validation function
- field.validity.valid = LegacyValidation(field);
-
- // if "invalid" events are required, trigger it here
-
- }
-
- if (field.validity.valid) {
-
- // remove error styles and messages
-
- }
- else {
-
- // style field, show error, etc.
-
- // form is invalid
- formvalid = false;
- }
-
- }
-
- // cancel form submit if validation fails
- if (!formvalid) {
- if (event.preventDefault) event.preventDefault();
- }
- return formvalid;
- }
-
-
- // basic legacy validation checking
- function LegacyValidation(field) {
-
- var
- valid = true,
- val = field.value,
- type = field.getAttribute("type"),
- chkbox = (type === "checkbox" || type === "radio"),
- required = field.getAttribute("required"),
- minlength = field.getAttribute("minlength"),
- maxlength = field.getAttribute("maxlength"),
- pattern = field.getAttribute("pattern");
-
- // disabled fields should not be validated
- if (field.disabled) return valid;
-
- // value required?
- valid = valid && (!required ||
- (chkbox && field.checked) ||
- (!chkbox && val !== "")
- );
-
- // minlength or maxlength set?
- valid = valid && (chkbox || (
- (!minlength || val.length >= minlength) &&
- (!maxlength || val.length <= maxlength)
- ));
-
- // test pattern
- if (valid && pattern) {
- pattern = new RegExp(pattern);
- valid = pattern.test(val);
- }
-
- return valid;
- }
LegacyValidation
特意保留为简单; 它会检查required
, minlength
, maxlength
和pattern
正则表达式,但是您将需要其他代码来检查电子邮件,URL,日期,数字,范围等。
这就引出了一个问题: 如果您要为旧版浏览器编写现场验证代码,为什么还要麻烦使用本机浏览器API? 很好! 仅当您想支持IE6以上的所有浏览器并提供类似的用户体验时,才需要上面的代码。 并非总是必要的……
但是请记住,始终使用正确的HTML5字段类型。 这些浏览器将提供本机输入控件,并在禁用JavaScript的情况下强制执行更快的客户端验证。
From: https://www.sitepoint.com/html5-forms-javascript-constraint-validation-api/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。