当前位置:   article > 正文

HTML5表单:JavaScript和约束验证API

h5表单验证api

对于这个由三部分组成的系列有关HTML5 Web表单的最后一篇文章,我们将讨论JavaScript集成和约束验证API。 如果您尚未这样做,请阅读The MarkupCSS文章,以确保您熟悉这些概念。

HTML5允许我们无需任何JavaScript编码即可实现客户端表单验证。 但是,在实现更复杂的表单时,我们需要增强本机验证,因为:

  • 并非所有浏览器都支持所有HTML5输入类型和CSS选择器
  • 错误消息气泡使用通用文本(“请填写此字段”)并且难以设置样式
  • :invalid:required样式将在用户与表单进行交互之前应用于页面加载。

大量的JavaScript魔术和Constraint Validation API可以改善用户体验。 请注意,如果您想支持我们将竭尽所能的各种浏览器和输入类型,可能会有些混乱。

截取表格

在HTML5之前,客户端验证涉及在表单上附加一个submit处理程序,该处理程序将验证字段,显示错误并防止Submit事件。

在HTML5中,浏览器将首先执行自己的验证-在表单有效之前,将不会触发submit事件。 因此,如果您想做一些复杂的事情,例如显示自己的错误,比较或自动填充字段,则必须通过将表单的noValidate属性设置为true来关闭本机验证:

  1. var form = document.getElementById("myform");
  2. form.noValidate = true;
  3. // set handler to validate the form
  4. // onsubmit used for easier cross-browser compatibility
  5. form.onsubmit = validateForm;

当然,这意味着您必须检查代码中的字段错误,但是仍然可以利用本机浏览器验证,我们将在不久后看到。

字段.willValidate属性

每个输入字段都有一个.willValidate属性。 返回:

  • 当浏览器将本地验证字段时为true
  • 当浏览器将不验证该字段时为false ,或者
  • 当浏览器不支持本地HTML5验证(例如IE8)时, 未定义

由于我们在上面禁用了本机验证,因此每个字段都将返回false。 让我们创建一个validateForm处理程序,该处理程序遍历所有字段并检查本地验证是否可用:

  1. function validateForm(event) {
  2. // fetch cross-browser event object and form node
  3. event = (event ? event : window.event);
  4. var
  5. form = (event.target ? event.target : event.srcElement),
  6. f, field, formvalid = true;
  7. // loop all fields
  8. for (f = 0; f < form.elements; f++) {
  9. // get field
  10. field = form.elements[f];
  11. // ignore buttons, fieldsets, etc.
  12. if (field.nodeName !== "INPUT" && field.nodeName !== "TEXTAREA" && field.nodeName !== "SELECT") continue;

循环遍历表单的elements集合中的所有字段,并检查它们是否是输入,而不是其他类型(例如按钮和字段集)。 下一行很重要…

  1. // is native browser validation available?
  2. if (typeof field.willValidate !== "undefined") {
  3. // native validation available
  4. }
  5. else {
  6. // native validation not available
  7. }

falseundefined都是falsey值,因此您不能仅检查field.willValidate

现在我们知道第一个块中的代码将评估何时可以使用本机验证。 然而…

浏览器是否支持输入类型?

如果阅读了第一部分 ,您会记得不支持的输入类型会回到text 。 例如:

<input type="date" name="dob" />

Firefox 29或IE11本身不支持。 这些浏览器将(有效)呈现:

<input type="text" name="dob" />

但是两种浏览器都支持text类型的验证,因此field.willValidate不会返回undefined ! 因此,我们必须检查我们的type属性是否与对象的.type属性匹配-如果不匹配,则需要实施旧版后备验证,例如

  1. // native validation available
  2. if (field.nodeName === "INPUT" && field.type !== field.getAttribute("type")) {
  3. // input type not supported! Use legacy JavaScript validation
  4. }

Field .checkValidity()方法

如果可以使用本机验证,则可以执行.checkValidity()方法来验证该字段。 如果没有问题,则该方法返回true,否则返回false

有一个类似的.reportValidity()方法,它无需重新检查即可返回当前状态,尽管这种方法用处不大,并非所有浏览器都支持。

两种方法还将:

  1. 设置字段的.validity对象,以便可以更详细地检查错误,并且
  2. 验证失败时,在字段上触发invalid事件。 这可用于显示错误,更改颜色等。请注意,没有相应的valid事件,因此请记住在必要时重置错误样式和消息。

字段.validity对象

.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

您可以在旧版浏览器中手动模拟.validity对象,例如

  1. // native validation not available
  2. field.validity = field.validity || {};
  3. // set to result of validation function
  4. field.validity.valid = LegacyValidation(field);

这样可以确保可以在所有浏览器中测试.validity.valid

字段.setCustomValidity()方法

可以传递.setCustomValidity()方法:

  • 一个空字符串。 这.checkValidity()字段设置为有效,因此.checkValidity().validity.valid将返回true ,或者
  • 一个包含错误消息的字符串,它将显示在消息提示框中(如果使用)。 该消息还会将字段标记为失败,因此.checkValidity().validity.valid将返回false,并且将触发invalid事件。

请注意,您还可以使用字段的.validationMessage属性检查当前消息。

全部放在一起

现在,我们有了一个简单的通用跨浏览器表单验证系统的基础:

  1. var form = document.getElementById("myform");
  2. form.noValidate = true;
  3. // set handler to validate the form
  4. // onsubmit used for easier cross-browser compatibility
  5. form.onsubmit = validateForm;
  6. function validateForm(event) {
  7. // fetch cross-browser event object and form node
  8. event = (event ? event : window.event);
  9. var
  10. form = (event.target ? event.target : event.srcElement),
  11. f, field, formvalid = true;
  12. // loop all fields
  13. for (f = 0; f < form.elements; f++) {
  14. // get field
  15. field = form.elements[f];
  16. // ignore buttons, fieldsets, etc.
  17. if (field.nodeName !== "INPUT" && field.nodeName !== "TEXTAREA" && field.nodeName !== "SELECT") continue;
  18. // is native browser validation available?
  19. if (typeof field.willValidate !== "undefined") {
  20. // native validation available
  21. if (field.nodeName === "INPUT" && field.type !== field.getAttribute("type")) {
  22. // input type not supported! Use legacy JavaScript validation
  23. field.setCustomValidity(LegacyValidation(field) ? "" : "error");
  24. }
  25. // native browser check
  26. field.checkValidity();
  27. }
  28. else {
  29. // native validation not available
  30. field.validity = field.validity || {};
  31. // set to result of validation function
  32. field.validity.valid = LegacyValidation(field);
  33. // if "invalid" events are required, trigger it here
  34. }
  35. if (field.validity.valid) {
  36. // remove error styles and messages
  37. }
  38. else {
  39. // style field, show error, etc.
  40. // form is invalid
  41. formvalid = false;
  42. }
  43. }
  44. // cancel form submit if validation fails
  45. if (!formvalid) {
  46. if (event.preventDefault) event.preventDefault();
  47. }
  48. return formvalid;
  49. }
  50. // basic legacy validation checking
  51. function LegacyValidation(field) {
  52. var
  53. valid = true,
  54. val = field.value,
  55. type = field.getAttribute("type"),
  56. chkbox = (type === "checkbox" || type === "radio"),
  57. required = field.getAttribute("required"),
  58. minlength = field.getAttribute("minlength"),
  59. maxlength = field.getAttribute("maxlength"),
  60. pattern = field.getAttribute("pattern");
  61. // disabled fields should not be validated
  62. if (field.disabled) return valid;
  63. // value required?
  64. valid = valid && (!required ||
  65. (chkbox && field.checked) ||
  66. (!chkbox && val !== "")
  67. );
  68. // minlength or maxlength set?
  69. valid = valid && (chkbox || (
  70. (!minlength || val.length >= minlength) &&
  71. (!maxlength || val.length <= maxlength)
  72. ));
  73. // test pattern
  74. if (valid && pattern) {
  75. pattern = new RegExp(pattern);
  76. valid = pattern.test(val);
  77. }
  78. return valid;
  79. }

LegacyValidation特意保留为简单; 它会检查requiredminlengthmaxlengthpattern正则表达式,但是您将需要其他代码来检查电子邮件,URL,日期,数字,范围等。

这就引出了一个问题: 如果您要为旧版浏览器编写现场验证代码,为什么还要麻烦使用本机浏览器API? 很好! 仅当您想支持IE6以上的所有浏览器并提供类似的用户体验时,才需要上面的代码。 并非总是必要的……

  • 对于简单的表单,您可能不需要任何JavaScript代码。 那些使用旧版浏览器的用户可能会退回到服务器端验证-应该始终予以实施。
  • 如果您需要更复杂的表单,但只需要支持最新的浏览器(IE10 +),则可以删除所有旧的验证代码。 如果您的表单使用的日期是Firefox和IE当前不支持的日期,则只需使用其他JavaScript。
  • 即使您确实需要代码来检查IE9及以下版本中的电子邮件,数字等字段,也请使其保持简单,并在停止支持这些浏览器后将其删除。 现在有点混乱,但是情况会有所改善。

但是请记住,始终使用正确的HTML5字段类型。 这些浏览器将提供本机输入控件,并在禁用JavaScript的情况下强制执行更快的客户端验证。

From: https://www.sitepoint.com/html5-forms-javascript-constraint-validation-api/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/110769
推荐阅读
相关标签
  

闽ICP备14008679号