HTML5表单原生校验是从无到有的根本性升级,通过required、type、pattern等属性实现自动UI提示与提交阻止;checkValidity()静默校验,reportValidity()触发提示;setCustomValidity()覆盖而非补充校验,需手动重置;ValidityState各字段浏览器兼容性差异大,须结合正则兜底。
传统 HTML(即 HTML4/XHTML)本身没有表单验证能力,所谓“验证”全靠 JavaScript 手写或第三方库。HTML5 引入了 required、type="email"、pattern、min/max 等属性,浏览器会自动触发 UI 提示(如红色边框、气泡提示)并阻止表单提交——这是本质区别,不是“增强”,而是从无到有。
checkValidity() 和 reportValidity() 是关键控制点这两个方法决定了你能否绕过/干预原生校验行为:
checkValidity() 只返回布尔值,不触发界面反馈,适合静默校验逻辑reportValidity() 不仅校验,还会触发浏览器默认错误提示(含焦点滚动、气泡),常用于手动触发校验(比如点击“下一步”时)form.reportValidity() 会逐个检查所有带校验属性的字段,任一失败就返回 false 并显示提示event.preventDefault() 阻止了 submit 事件,必须显式调用 reportValidity(),否则用户看不到任何反馈setCustomValidity() 能覆盖原生错误但容易误用它不是“添加自定义错误”,而是“替换当前字段的验证状态”。空字符串表示通过,非空字符串表示失败并显示该文本:
input.setCustomValidity('邮箱已被注册'),原生 type="email" 校验就失效了——即使输入的是非法邮箱,也不会再报“请填写有效邮箱”input 事件,在校验通过时调用 input.setCustomValidity('')
pattern 和 setCustomValidity(),逻辑易混乱;优先用 pattern 做正则约束,只在需要服务端联动(如用户名唯一性)时用 setCustomValidity()
validity 对象的支持细节不一致input.validity 是一个 ValidityState 对象,但各字段兼容性有坑:
立即学习“前端免费学习笔记(深入)”;
validity.badInput:Chrome 支持,Safari 16.4+ 才支持,Firefox 始终为 false(即使输入了非数字到 type="number")validity.customError 在调用 setCustomValidity(str) 后才为 tru
e,但某些旧版 Edge 不触发 invalid 事件validity.typeMismatch 对 type="email" 或 type="url" 有效,但对 type="date" 在 Safari 中可能不触发(它允许空值或非法格式而不报错)validity.xxx 字段,应结合 checkValidity() + 自定义正则兜底原生校验看似省事,但 validity 对象字段行为不统一、setCustomValidity() 的覆盖逻辑容易误伤、以及 Safari 对日期/数字类型校验的宽松处理,都是上线前必须实测的点。