JS 表单验证实战
学习表单验证 · 难度:进阶 · +15XP
JavaScript 表单验证实战
表单验证(Form Validation)是 Web 开发中最常见的需求之一。JavaScript 可以实现在提交前对用户输入进行客户端验证,即时反馈错误信息,大幅提升用户体验。相比纯 HTML5 验证,JavaScript 验证提供了更大的灵活性和自定义能力。
HTML5 内置验证属性
required:必填字段pattern:正则表达式匹配type="email":邮箱格式验证minlength/maxlength:字符长度限制
<!-- HTML5 内置验证 -->
<form id="myForm" novalidate>
<input type="text" id="username" required minlength="3" maxlength="20"
placeholder="请输入用户名">
<input type="email" id="email" required placeholder="请输入邮箱">
<input type="password" id="password" required
pattern="^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$"
placeholder="至少8位,含字母和数字">
<input type="tel" id="phone" pattern="^1[3-9]\d{9}$"
placeholder="请输入手机号">
<button type="submit">提交</button>
</form>
JavaScript 自定义验证
| 验证方法 | 适用场景 | 示例 |
|---|---|---|
| 正则表达式验证 | 邮箱、手机号、身份证 | /^1[3-9]\d{9}$/.test(phone) |
| 长度验证 | 用户名、密码、验证码 | value.length >= 6 |
| 比较验证 | 确认密码、日期范围 | pwd === confirmPwd |
| 自定义逻辑 | 业务规则、异步校验 | 检查用户名是否已存在 |
完整验证实现
class FormValidator {
constructor(formId) {
this.form = document.getElementById(formId);
this.rules = {};
this.errors = {};
this.form.onsubmit = (e) => {
e.preventDefault();
if (this.validate()) this.onSuccess();
};
}
// 添加验证规则
addRule(field, validators) {
this.rules[field] = validators;
}
// 执行验证
validate() {
this.errors = {};
let isValid = true;
for (const [field, validators] of Object.entries(this.rules)) {
const input = document.getElementById(field);
const value = input.value.trim();
const fieldErrors = [];
for (const { test, message } of validators) {
if (!test(value)) {
fieldErrors.push(message);
isValid = false;
}
}
if (fieldErrors.length > 0) {
this.errors[field] = fieldErrors;
}
}
this.showErrors();
return isValid;
}
showErrors() {
// 清除旧错误
document.querySelectorAll('.error-msg')
.forEach(el => el.remove());
// 显示新错误
for (const [field, messages] of Object.entries(this.errors)) {
const input = document.getElementById(field);
input.classList.add('error');
const errDiv = document.createElement('div');
errDiv.className = 'error-msg';
errDiv.style.color = 'red';
errDiv.textContent = messages[0];
input.parentNode.appendChild(errDiv);
}
// 清除成功字段的错误状态
document.querySelectorAll('input:not(.error)')
.forEach(el => el.classList.remove('error'));
}
onSuccess() {
console.log('验证通过,提交表单!');
this.form.submit();
}
}
// 使用示例
const validator = new FormValidator('myForm');
validator.addRule('username', [
{ test: v => v.length >= 3, message: '用户名至少3个字符' },
{ test: v => v.length <= 20, message: '用户名最多20个字符' },
{ test: v => /^[a-zA-Z0-9_]+$/.test(v), message: '用户名只能包含字母数字和下划线' }
]);
validator.addRule('email', [
{ test: v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v), message: '请输入有效的邮箱地址' }
]);
validator.addRule('phone', [
{ test: v => /^1[3-9]\d{9}$/.test(v), message: '请输入有效的手机号码' }
]);
实时验证与异步验证
// 实时验证:输入时即时反馈
input.addEventListener('input', () => {
const value = input.value.trim();
if (value.length < 3) {
showError(input, '至少3个字符');
} else {
clearError(input);
}
});
// 失焦验证
input.addEventListener('blur', () => {
validateField(input);
});
// 异步验证:检查用户名是否已存在
async function checkUsername(username) {
try {
const res = await fetch('/api/check-username?name=' + username);
const data = await res.json();
return data.available; // true/false
} catch (err) {
console.error('验证失败:', err);
return false;
}
}
// 在验证规则中使用异步验证
input.addEventListener('blur', async () => {
const available = await checkUsername(input.value);
if (!available) {
showError(input, '该用户名已被占用');
}
});