HTML 表单和约束验证的完整指南

2021-09-13 11:34:08 浏览数 (1)

在本文中,我们将研究 HTML 表单字段和 HTML5 提供的验证选项。我们还将研究如何通过使用 CSS 和 JavaScript 来增强这些功能。

什么是约束验证?

每个表单域都有一个目的。并为此经常管辖约束上或理事什么应该和不应该被输入到每个表单域的规则- 。例如,一个email字段需要一个有效的电子邮件地址;一个password字段可能需要某些类型的字符,并且有最少数量的必需字符;并且文本字段可能对可以输入的字符数有限制。

现代浏览器能够检查用户是否遵守了这些约束,并可以在违反这些规则时向他们发出警告。这称为约束验证

客户端与服务器端验证

在语言早期编写的大多数 JavaScript 代码处理客户端表单验证。即使在今天,开发人员仍花费大量时间编写函数来检查字段值。这在现代浏览器中仍然必要吗?可能不是。在大多数情况下,这实际上取决于您要尝试做什么。

但首先,这里有一个重要的警告信息:

客户端验证是一项很好的功能,它可以在应用程序浪费时间和带宽将数据发送到服务器之前防止常见的数据输入错误。它不能替代服务器端验证! 始终清理服务器端的数据。并非每个请求都来自浏览器。即使这样做,也不能保证浏览器验证数据。任何知道如何打开浏览器开发工具的人也可以绕过您精心制作的 HTML 和 JavaScript。

HTML5 输入字段

HTML 提供:

  • <textarea> 用于多行文本框
  • <select> 用于选项的下拉列表
  • <button> 用于……按钮

但你<input>最常使用的是:

代码语言:javascript复制
<input type="text" name="username" />

type属性设置控件类型,并且有很多选项可供选择:

type

描述

button

一个没有默认行为的按钮

checkbox

一个复选框

color

颜色选择器

date

年、月、日的日期选择器

datetime-local

日期和时间选择器

email

电子邮件输入字段

file

文件选择器

hidden

一个隐藏的领域

image

显示由src属性定义的图像的按钮

month

月份和年份选择器

number

数字输入字段

password

带有模糊文本的密码输入字段

radio

一个单选按钮

range

滑块控件

reset

将所有表单输入重置为其默认值的按钮(但请避免使用它,因为它很少有用)

search

搜索输入字段

submit

一个表单提交按钮

tel

电话号码输入字段

text

文本输入字段

time

没有时区的时间选择器

url

URL 输入字段

week

周数和年份选择器

text如果您省略该type属性或它不支持某个选项,则浏览器会回退到。现代浏览器对所有类型都有很好的支持,但旧浏览器仍会显示文本输入字段。

其他有用的<input>属性包括:

属性

描述

accept

文件上传类型

alt

图像类型的替代文本

autocomplete

字段自动完成提示

autofocus

页面加载时的焦点字段

capture

媒体捕捉输入法

checked

复选框/收音机被选中

disabled

禁用控件(它不会被验证或提交其值)

form

与使用此 ID 的表单关联

formaction

提交和图像按钮上提交的 URL

inputmode

数据类型提示

list

自动完成选项的ID<datalist>

max

最大值

maxlength

最大字符串长度

min

最小值

minlength

最小字符串长度

name

提交给服务器的控件名称

pattern

正则表达式模式,例如[A-Z] 一个或多个大写字符

placeholder

字段值为空时的占位符文本

readonly

该字段不可编辑,但仍将被验证并提交

required

该字段是必需的

size

控件的大小(通常在 CSS 中被覆盖)

spellcheck

设置true或false拼写检查

src

图片网址

step

数字和范围的增量值

type

字段类型(见上文)

value

初始值

HTML 输出字段

除了输入类型,HTML5 还提供只读输出:

  • output: 计​​算或用户操作的文本结果
  • progress: 带有valuemax属性的进度条
  • meter:它可以根据对设定的值绿色,琥珀色和红色之间改变规模valueminmaxlowhigh,和optimum属性。

输入标签

字段应该有一个关联的<label>,您可以将其包裹在元素周围:

代码语言:javascript复制
<label>your name <input type="text" name="name" /><label>

或者id使用for属性将字段链接到标签:

代码语言:javascript复制
<label for="nameid">your name</label>
<input type="text" id="nameid" name="name" />

标签对于可访问性很重要。您可能遇到过使用 aplaceholder来节省屏幕空间的表单:

代码语言:javascript复制
<input type="text" name="name" value="" placeholder="your name" />

一旦用户输入内容,占位符文本就会消失——即使是一个空格。最好显示标签而不是强迫用户记住该字段想要什么!

输入行为

字段类型和约束属性会改变浏览器的输入行为。例如,number输入显示移动设备上的数字键盘。该字段可能会显示一个微调器,键盘上/下光标按下将增加和减少值。

大多数字段类型是显而易见的,但也有例外。例如,信用卡是数字,但增量/减量微调器没用,输入 16 位数字时很容易向上或向下按。最好使用标准text类型,但将inputmode属性设置为numeric,这会显示合适的键盘。设置autocomplete="cc-number"还建议任何预先配置或以前输入的卡号。

使用正确的字段typeautocorrect提供在 JavaScript 中难以实现的好处。例如,一些移动浏览器可以:

  • 通过使用相机扫描卡来导入信用卡详细信息
  • 导入短信发送的一次性代码

自动验证

该浏览器可以确保与由定义的约束的输入值附着typeminmaxstepminlengthmaxlengthpattern,和required属性。例如:

代码语言:javascript复制
<input type="number" min="1" max="100" required />

尝试提交空值会阻止表单提交并在 Chrome 中显示以下消息:

微调器不允许 1 到 100 范围之外的值。如果您键入的字符串不是数字,则会出现类似的验证消息。所有这些都没有一行 JavaScript。

您可以通过以下方式停止浏览器验证:

  • novalidate<form>元素添加一个属性
  • formnovalidate提交按钮或图像添加属性

创建自定义 JavaScript 输入

如果您正在编写一个新的基于 JavaScript 的日期输入组件,请停止并远离您的键盘!

编写自定义输入控件很困难。您必须考虑鼠标、键盘、触摸、语音、可访问性、屏幕尺寸以及 JavaScript 失败时会发生什么。您也在创造不同的用户体验。也许你的控制比桌面、iOS 和 Android 上的标准日期选择器要好,但不熟悉的 UI 会让一些用户感到困惑。

开发人员选择创建基于 JavaScript 的输入有三个主要原因。

1. 标准控件难以设计风格

CSS 样式是有限的,通常需要技巧,例如用标签::before::after伪元素覆盖输入。情况正在改善,但质疑任何将形式置于功能之上的设计。

2.<input>旧浏览器不支持现代类型

本质上,您正在为 Internet Explorer 编码。IE 用户不会获得日期选择器,但仍可以按YYYY-MM-DD格式输入日期。如果您的客户坚持,则仅在 IE 中加载 polyfill。没有必要给现代浏览器增加负担。

3. 您需要一种以前从未实现过的新输入类型

这些情况很少见,但总是从适当的 HTML5 字段开始。它们很快,甚至在脚本加载之前它们就可以工作。您可以根据需要逐步增强字段。例如,少量的 JavaScript 可以确保日历事件的结束日期发生在开始日期之后。

总之:避免重新发明 HTML 控件!

CSS 验证样式

您可以将以下伪类应用于输入字段以根据当前状态对其进行样式设置:

选择器

描述

:focus

重点领域

:focus-within

一个元素包含一个具有焦点的字段(是的,它是一个父选择器!)

:focus-visible

由于键盘导航,元素具有焦点,因此需要焦点环或更明显的样式

:required

具有required属性的字段

:optional

没有required属性的字段

:valid

已通过验证的字段

:invalid

未通过验证的字段

:user-valid

在用户与其交互后通过验证的字段(仅限 Firefox)

:user-invalid

用户与其交互后未通过验证的字段(仅限 Firefox)

:in-range

该值在 anumber或range输入的范围内

:out-of-range

该值超出了 anumber或range输入的范围

:disabled

具有disabled属性的字段

:enabled

没有disabled属性的字段

:read-only

具有read-only属性的字段

:read-write:

没有read-only属性的字段

:checked

选中的复选框或单选按钮

:indeterminate

不确定的复选框或单选状态,例如取消选中所有单选按钮时

:default

默认提交按钮或图像

您可以placeholder使用::placeholder伪元素设置输入文本的样式:

代码语言:javascript复制
/* blue placeholder on email fields */
input[type="email"]::placeholder {
  color: blue;
}

上面的选择器具有相同的特性,因此顺序可能很重要。考虑这个例子:

代码语言:javascript复制
input:invalid { color: red; }
input:enabled { color: black; }

无效输入具有红色文本,但它仅适用于具有disabled属性的输入——因此所有启用的输入都是黑色的。

浏览器在页面加载时应用验证样式。例如,在下面的代码中,每个无效字段都有一个红色边框:

代码语言:javascript复制
:invalid {
  border-color: #900;
}

用户在与表单交互之前会遇到一组令人生畏的红色框。在第一次提交后或更改值时显示验证错误将提供更好的体验。这就是 JavaScript 介入的地方……

JavaScript 和约束验证 API

该约束验证API提供了可增强标准的HTML现场检查表单自定义选项。你可以:

  • 停止验证,直到用户与字段交互或提交表单
  • 使用自定义样式显示错误消息
  • 提供仅在 HTML 中无法实现的自定义验证。当您需要比较两个输入时,这通常是必要的——例如,当您输入电子邮件地址或电话号码时,检查“新”和“确认”密码字段是否具有相同的值,或确保一个日期接一个日期。

表单验证

在使用 API 之前,您的代码应该通过将表单的noValidate属性设置为true(与添加novalidate属性相同)来禁用默认验证和错误消息:

代码语言:javascript复制
const myform = document.getElementById('myform');
myform.noValidate = true;

然后你可以添加事件处理程序——比如当表单提交时:

代码语言:javascript复制
myform.addEventListener('submit', validateForm);

处理程序可以使用checkValidity()orreportValidity()方法检查整个表单是否有效,true当表单的所有输入都有效时返回。(不同之处在于checkValidity()检查是否有任何输入受约束验证。)

Mozilla 文档解释说:

invalid每个无效字段也会触发一个事件。这不会冒泡:必须将处理程序添加到使用它的每个控件中。

代码语言:javascript复制
// validate form on submission
function validateForm(e) {

  const form = e.target;

  if (form.checkValidity()) {

    // form is valid - make further checks

  }
  else {

    // form is invalid - cancel submit
    e.preventDefault();

  }

};

有效的表单现在可能会导致进一步的验证检查。同样,无效表单可能会突出显示无效字段。

现场验证

各个字段具有以下约束验证属性:

  • willValidate:true如果元素是约束验证的候选元素,则返回。
  • validationMessage: 验证消息。如果该字段有效,这将是一个空字符串。
  • valitity:一个ValidityState 对象。当字段有效时,它有一个valid属性集true。如果是false,则以下一项或多项属性将是true: 有效性状态描述.badInput浏览器无法理解输入.customError已设置自定义有效性消息.patternMismatch该值与指定的pattern属性不匹配.rangeOverflow值大于max属性.rangeUnderflow值小于min属性.stepMismatch该值不符合step属性规则.tooLong字符串长度大于maxlength属性.tooShort字符串长度小于minlength属性.typeMismatch该值不是有效的电子邮件或 URL.valueMissing一个required值为空

各个字段具有以下约束验证方法:

  • setCustomValidity(message): 为无效字段设置错误消息。当该字段有效时必须传递一个空字符串,否则该字段将永远无效。
  • checkValidity():true当输入有效时返回。该valitity.valid属性执行相同的操作,但checkValidity()还会invalid在该字段上触发一个可能有用的事件。

validateForm()处理函数可以遍历各个领域,并应用invalid类,它的父元素在必要时:

代码语言:javascript复制
function validateForm(e) {
  const form = e.target;
  if (form.checkValidity()) {
    // form is valid - make further checks
  }
  else {
    // form is invalid - cancel submit
    e.preventDefault();
    // apply invalid class
    Array.from(form.elements).forEach(i => {
      if (i.checkValidity()) {
        // field is valid - remove class
        i.parentElement.classList.remove('invalid');
      }
      else {
        // field is invalid - add class
        i.parentElement.classList.add('invalid');
      }
    });
  }
};

假设您的 HTML 定义了一个电子邮件字段:

代码语言:javascript复制
<div>
  <label for="email">email</label>
  <input type="email" id="email" name="email" required />
  <p class="help">Please enter a valid email address</p>
</div>

当电子邮件未指定或无效时,脚本将invalid类应用到<div>。CSS 可以在表单提交时显示或隐藏验证消息:

代码语言:javascript复制
.help { display: none; }
.invalid .help { display: block; }
.invalid label, .invalid input, .invalid .help {
  color: red;
  border-color: red;
}

创建自定义表单验证器

以下演示显示了一个示例联系表单,它需要用户名和电子邮件地址、电话号码或两者:

它是使用名为 的通用表单验证类实现的FormValidate。实例化对象时传递表单元素。可以设置可选的第二个参数:

  • true 在用户与其交互时验证每个字段
  • false (默认)在第一次提交后验证所有字段(在此之后进行字段级验证)
代码语言:javascript复制
// validate contact form
const contactForm = new FormValidate(document.getElementById('contact'), false);

一个.addCustom(field, func)方法定义了自定义验证函数。以下代码确保emailtel字段有效(都没有required属性):

代码语言:javascript复制
// custom validation - email and/or telephone
const
  email = document.getElementById('email'),
  tel = document.getElementById('tel');

contactForm.addCustom(email, f => f.value || tel.value);
contactForm.addCustom(tel, f => f.value || email.value);

一个FormValidate对象监视以下两个:

  • focusout 事件,然后检查单个字段
  • 表单submit事件,然后检查每个字段

两者都调用该.validateField(field)方法,该方法检查字段是否通过标准约束验证。当它这样做时,分配给该字段的任何自定义验证功能将依次执行。必须全部返回true才能使该字段有效。

无效字段具有invalid应用于该字段的父元素的类,该类使用 CSS 显示红色帮助消息。

最后,submit当整个表单有效时,对象调用自定义函数:

代码语言:javascript复制
// custom submit
contactForm.submit = e => {
  e.preventDefault();
  alert('Form is valid!n(open the console)');
  const fd = new FormData(e.target);
  for (const [name, value] of fd.entries()) {
    console.log(name   ': '   value);
  }
}

或者,您可以使用标准addEventListener来处理表单submit事件,因为FormValidate当表单无效时可以防止进一步的处理程序运行。

形式技巧

表单是所有 Web 应用程序的基础,开发人员花费大量时间处理用户输入。约束验证得到很好的支持:浏览器可以处理大多数检查并显示适当的输入选项。

建议:

  • 尽可能使用标准的 HTML 输入类型。集minmaxstepminlengthmaxlengthpatternrequiredinputmode,和autocomplete属性适当。
  • 如有必要,使用一点 JavaScript 来启用自定义验证和消息。
  • 对于更复杂的字段,逐步增强标准输入。

最后:忘记 Internet Explorer!

除非您的客户主要是 IE 用户,否则没有必要实现您自己的回退验证功能。所有 HTML5 输入字段都可以在 IE 中使用,但可能需要更多的用户努力。(例如,当您输入无效的电子邮件地址时,IE 不会检测到。)您仍然需要验证服务器上的数据,因此请考虑将其用作 IE 错误检查的基础。

0 人点赞