JavaScript表单验证需拦截无效提交、给出明确反馈且不破坏体验;须结合原生checkValidity()/reportValidity()、即时反馈监听、自定义规则及可访问性处理。
JavaScript 表单验证不是“加个 onsubmit 就完事”,关键在于**拦截无效提交 + 给出明确反馈 + 不破坏用户体验**。纯前端验证仅作辅助,后端校验不可省略。
checkValidity() 和 reportValidity() 快速启用原生验证HTML5 表单控件(、required、minlength 等)自带验证逻辑,但默认只在提交时触发。想手动检查或提前提示:
element.checkValidity() 返回布尔值,不显示错误气泡element.reportValidity() 返回布尔值,同时触发浏览器默认错误提示(含定位和文案)form.reportValidity() 会检查所有带约束的字段并高亮首个无效项setCustomValidity("...") 后必须显式调用 reportValidity() 才能显示该消息input 和 blur 实现即时反馈等用户点提交才报错体验差。更合理的是:input 时做轻量校验(如邮箱格式),blur(失焦)时做较重校验(如用户名是否被占用):
input 事件适合防抖后检查格式(避免每敲一个字都请求)blur 事件适合发起异步校验(如查重),此时用户已明确“填完了这个字段”input 中直接弹 alert 或覆盖输入框内容,改用旁注提示(如 )setCustomValidity(""),否则 checkValidity() 一直返回 false
pattern 的坑pattern 属性只支持正则,且默认是“全字符串匹配”(隐式加 ^ 和 $),但容易误用:
✅ 正确:必须且只能是 6 位数字 ❌ 错误:只要包含连续 6 位数字就通过(如 "abc123456def")setCustomValidity(),比硬塞进 pattern 更可控pattern 错误提示文案无法自定义,只能靠 title 属性(部分浏览器不显
常见做法是校验失败时 button.disabled = true,但这会切断屏幕阅读器用户的操作流:
aria-disabled="true",否则 AT(辅助技术)可能忽略禁用状态event.preventDefault() 并聚焦首个错误字段disabled 属性后提交最易被忽略的一点:验证逻辑和 UI 提示必须严格对应。比如 JS 校验了密码强度,但 HTML 没写 minlength,那么 reportValidity() 就不会触发该字段的原生提示——两者要对齐,否则用户看到的错误信息和实际校验点脱节。