Skip to content

Forms API

HTML5 引入了约束验证 API(Constraint Validation API),它允许浏览器根据设置在表单元素上的属性原生验证表单输入。JavaScript 可以与此 API 交互,检查有效性并自定义验证消息。

这些属性启用内置浏览器验证:

  • required: 指定输入字段必须填写。
  • type:(例如,email、url、number、date)为格式提供固有的验证。
  • min 和 max: 指定数字或日期输入的最小值和最大值。
  • minlength 和 maxlength: 指定文本输入的最小和最大长度。
  • pattern: 指定输入值必须匹配的正则表达式。

带有验证属性的 HTML 表单示例:

<form id="myForm">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<br><br>
<label for="age">Age (18-99):</label>
<input type="number" id="age" name="age" min="18" max="99" required>
<br><br>
<label for="password">Password (min 8 chars, 1 number, 1 uppercase):</label>
<input type="password" id="password" name="password" minlength="8"
pattern=".*(?=.*\d)(?=.*[A-Z]).*"
title="Must contain at least one number, one uppercase letter, and at least 8 characters."
required>
<br><br>
<button type="submit">Submit</button>
</form>
<p id="errorMessage" style="color: red;"></p>

当用户尝试提交带有基于这些属性的无效数据的表单时,浏览器通常会阻止提交并显示默认错误消息。

JavaScript 在输入元素上提供了方法和属性,用于与其有效性状态交互:

输入元素的 validity 属性返回一个 ValidityState 对象。此对象有几个布尔属性,指示元素可能无效的原因:

示例 1:检查有效性并显示 validationMessage

<input id="myNumberInput" type="number" min="100" max="300" required>
<button id="checkButton">Check Validity</button>
<p id="messageArea"></p>
<script>
const numberInput = document.getElementById('myNumberInput');
const checkButton = document.getElementById('checkButton');
const messageArea = document.getElementById('messageArea');
checkButton.addEventListener('click', function() {
if (numberInput.checkValidity()) {
messageArea.textContent = 'Input is valid!';
messageArea.style.color = 'green';
} else {
messageArea.textContent = numberInput.validationMessage;
messageArea.style.color = 'red';
}
});
</script>

示例 2:使用 ValidityState 属性提供特定反馈

<input id="ageInput" type="number" min="18" max="99">
<button id="checkAgeButton">Check Age</button>
<p id="ageMessage"></p>
<script>
const ageInput = document.getElementById('ageInput');
const checkAgeButton = document.getElementById('checkAgeButton');
const ageMessage = document.getElementById('ageMessage');
checkAgeButton.addEventListener('click', function() {
let message = '';
ageInput.checkValidity(); // Important to update validity state properties
if (ageInput.validity.rangeUnderflow) {
message = 'Value too small. Minimum age is 18.';
} else if (ageInput.validity.rangeOverflow) {
message = 'Value too large. Maximum age is 99.';
} else if (ageInput.validity.valueMissing) {
message = 'Age is required.';
} else if (ageInput.validity.valid) {
message = 'Age is valid.';
ageMessage.style.color = 'green';
} else {
message = 'Invalid input.'; // Generic fallback
}
ageMessage.textContent = message;
if (!ageInput.validity.valid) {
ageMessage.style.color = 'red';
}
});
</script>

示例 3:使用 setCustomValidity() 自定义验证消息

<form id="signupForm">
<label for="username">Username (min 5 chars):</label>
<input type="text" id="username" name="username" required minlength="5">
<button type="submit">Sign Up</button>
</form>
<script>
const signupForm = document.getElementById('signupForm');
const usernameInput = document.getElementById('username');
usernameInput.addEventListener('input', function() {
// Clear custom validity message on each input to allow native validation to re-evaluate
usernameInput.setCustomValidity('');
if (usernameInput.validity.tooShort) {
usernameInput.setCustomValidity('Username is too short! Please use at least 5 characters.');
} else if (usernameInput.value.toLowerCase() === 'admin') {
usernameInput.setCustomValidity('"admin" is not a permitted username.');
}
// Optional: report validity immediately on input
// usernameInput.reportValidity();
});
signupForm.addEventListener('submit', function(event) {
if (!signupForm.checkValidity()) {
event.preventDefault(); // Prevent form submission if invalid
// Browsers usually show validation messages on submit attempt
// You could add further custom logic here if needed
console.log('Form is invalid. Please correct errors.');
}
});
</script>
  • 客户端验证 vs 服务器端验证:客户端验证(如本 API)通过提供即时反馈来改善用户体验。然而,它不是安全措施。恶意用户可以绕过客户端验证。因此,始终在服务器端也实现强大的验证。
  • **为无效字段设置样式:**CSS 伪类(pseudo-classes)如 :valid、:invalid、:required、:optional 可用于根据表单元素的验证状态设置样式。
  • **可访问性:**确保验证消息对残障用户可访问(例如,通过使用 aria-describedby 将错误消息与表单字段关联)。

约束验证 API 为表单验证提供了一个强大的基础。对于更复杂的场景或高度自定义的 UI,你可以将其与自定义 JavaScript 逻辑结合使用,或使用专门的表单验证库。