原生html表单验证仅在submit时触发,不响应js赋值、粘贴及空值;type="email"校验宽松,pattern需加^$锚点且对number无效;实时校验须手动调用checkvalidity()或reportvalidity();novalidate必须加在form标签上。

原生 HTML 表单验证不是“设了属性就自动全程护航”,它只在 submit 事件触发时才检查,且对 JS 直接赋值、粘贴内容、空值容忍等场景完全不敏感——想靠 required 或 pattern 一招鲜解决所有问题,基本会踩坑。
为什么 type="email" 和 pattern 验证总“放水”?
浏览器对 type="email" 的校验极宽松:只要含一个 @ 和一个点号(如 a@b.c)就算通过;pattern 更容易被忽略锚点,写成 pattern="[0-9]{4}" 会导致 abc1234def 这种字符串也过关。
-
pattern必须显式加^和$,例如:pattern="^[0-9]{4}$" -
pattern只对type="text"、"email"、"tel"等生效,对type="number"完全无效 - 想严格校验邮箱,别依赖
type="email",改用type="text" pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"并配title -
type="number"允许粘贴字母、显示为空但checkValidity()仍返回true,必须配合min/max或 JS 补判
怎么让验证在输入时就反馈,而不是等到点提交?
原生验证默认只在 submit 时触发。要实现 blur 或 input 实时校验,必须手动调用 API。
- 监听
input或blur事件,然后调用element.checkValidity()判断状态(不弹提示) - 需要弹出浏览器默认气泡提示,必须调用
element.reportValidity()(注意:Firefox 不自动滚动到错误字段) - 对整个表单实时校验,用
form.reportValidity(),它会遍历所有带约束的子元素 - 若想自定义错误文案,先调
element.setCustomValidity("手机号格式错误"),再调reportValidity();清空错误必须设为空字符串:setCustomValidity("")
novalidate 属性该加在哪儿?加错就白加
novalidate 是 form 级开关,不是按钮或输入框的属性。加错位置等于没关。
- 正确写法:
<form novalidate></form> - 错误写法:
<button novalidate></button>或<input novalidate>—— 浏览器直接忽略 - 加了
novalidate后,required、pattern、type等全部失效,你得 100% 自己用 JS 补全所有逻辑(包括空值、格式、异步查重) - 低端安卓 WebView 中,原生验证气泡可能卡顿,这时禁用反而是合理选择,但别忘了补上视觉反馈和提交拦截
最容易被忽略的是 setCustomValidity('') 的调用时机:每次输入后都得清空上次的错误状态,否则哪怕用户已输对,reportValidity() 仍会弹出旧错误。验证逻辑越靠近用户操作路径(比如密码确认比对),越要小心状态残留和事件绑定范围。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











