JavaScript表单验证关键在何时校验、校验什么、失败后如何反馈;需结合HTML5原生属性与checkValidity()/reportValidity(),善用validity对象,并通过setCustomValidity()处理自定义规则,blur事件为实时校验平衡点。

JavaScript 表单验证不是“加个 onsubmit 就完事”,关键在**何时校验、校验什么、失败后怎么反馈**——纯前端验证只为体验,不能替代后端校验。
用 checkValidity() 和 reportValidity() 快速启用原生约束
HTML5 原生表单属性(required、type="email"、minlength、pattern)配合这两个 API,能零代码实现基础反馈:
-
checkValidity()返回true或false,不触发 UI 提示 -
reportValidity()返回布尔值,同时在首个无效字段显示浏览器默认气泡提示 - 注意:部分浏览器对
pattern的正则支持有差异(比如不支持^/$锚点),建议用test()手动补位
示例:
<input type="email" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}">
<button onclick="this.form.reportValidity()">提交</button>
手动校验时,别直接读 value —— 先看 validity 对象
input.validity 是浏览器解析原生约束后的结构化结果,比正则匹配更可靠,也避免重复造轮子:
-
validity.valueMissing→ 对应required未填 -
validity.typeMismatch→ 如type="email"输入了abc -
validity.patternMismatch→pattern不匹配 -
validity.tooShort/validity.tooLong→ 响应minlength/maxlength
这样写更健壮:
const input = document.querySelector('input[name="phone"]');
if (!input.checkValidity()) {
if (input.validity.valueMissing) console.log('手机号不能为空');
if (input.validity.patternMismatch) console.log('格式不正确,应为11位数字');
}
自定义规则(如手机号、身份证)必须用 setCustomValidity() 并重置
原生 validity 不包含业务逻辑,需手动干预。重点是:每次校验前必须先调用 setCustomValidity('') 清空旧状态,否则会永久阻塞提交:
立即学习“Java免费学习笔记(深入)”;
- 错误写法:
input.setCustomValidity('长度不对')只调一次 → 后续即使输入正确,checkValidity()仍返回false - 正确流程:
input.setCustomValidity('');→ 校验 →input.setCustomValidity('错误信息')(仅当失败时) - 推荐封装成函数,避免漏掉清空步骤
示例:
input.addEventListener('input', () => {
input.setCustomValidity(''); // 关键!
if (!/^1[3-9]\d{9}$/.test(input.value)) {
input.setCustomValidity('请输入有效的11位手机号');
}
});
实时校验(input 或 blur)的取舍很实际
用户还没输完就报错(如输到第3位就提示“邮箱格式错误”)会显著降低体验:
-
input事件适合防呆(如自动过滤非法字符),但不适合报错 -
blur(失焦)是平衡点:用户明确离开该字段时反馈,既及时又不干扰 - 密码确认类场景,必须在第二个字段
blur时比对两个值,不能只依赖单字段校验 - 移动端要注意
blur触发时机不稳定,可加setTimeout微调
真正难的是错误提示的 DOM 插入位置和样式一致性——浏览器默认气泡不可控,业务中大概率要自己 insertAdjacentHTML 插提示文案,并管理显隐逻辑。











