required、type、pattern组合可覆盖80%基础校验,但必须满足form包裹、submit触发等条件;required只判空不判格式,type="email"校验宽松,pattern仅对text类type生效且需配合title和setCustomValidity("")清空错误。

required、type、pattern 这三个属性组合起来,就能覆盖绝大多数基础格式校验需求——但必须用对,否则浏览器根本不触发。
为什么加了 required 却没反应?
不是属性失效,是触发条件没满足:required 只在表单提交(submit 事件)时校验,且只检查是否为空或未选中,不看内容本身。
- 输入框必须被
<form></form>包裹,否则浏览器不识别为表单控件 - 提交按钮得是
<button type="submit"></button>或<input type="submit">;用type="button"或直接调form.submit()会跳过所有原生校验 -
type="number"的required会忽略纯空格(如" "),但接受"123 "(尾部空格) - 判断“必填未填”的可靠依据是
element.validity.valueMissing === true,别依赖value === ""
type="email" 和 pattern 到底该用哪个?
type="email" 是语义化捷径,但校验极宽松:只要含一个 @ 和至少一个点号(如 a@b.c、user@localhost)就通过;pattern 才是真正可控的格式锁。
-
pattern只对type="text"、"email"、"url"、"password"等生效,对type="number"完全无效 - 浏览器自动把你的正则包进
^$,所以写pattern="[a-z]{3,}"就行,别写pattern="^[a-z]{3,}$"(Chrome 会报Invalid regular expression) - 中文需显式写入,如
pattern="[u4e00-u9fa5a-zA-Z0-9]{2,10}";w不匹配汉字 - 想排除开头数字?用负向先行断言:
pattern="(?!\d)[a-zA-Z0-9]{6,12}"(注意 JS 字符串里双反斜杠)
如何让校验实时反馈,而不是等提交?
原生验证默认只在提交时触发。要实时提示,必须手动调 API 并处理状态。
- 监听
input或blur事件,在回调里调element.checkValidity()判断结果 - 要用
element.reportValidity()才能弹出浏览器默认气泡——但 Firefox 不滚动到错误字段,Chrome 会;若需统一行为,建议自己渲染错误文案 - 自定义提示必须配合
setCustomValidity():校验失败时传字符串(如input.setCustomValidity("手机号格式不对")),通过时必须传空字符串(input.setCustomValidity("")),否则旧错误残留导致永远无法提交 -
invalid事件可捕获校验失败,但默认不冒泡,且不能阻止提交;它更适合做日志或埋点
容易被忽略的兼容性与安全边界
所有前端校验都只是第一道防线,novalidate 属性、开发者工具修改、禁用 JS 都能绕过它。
立即学习“前端免费学习笔记(深入)”;
- 后端必须重复校验,且规则要和前端一致,否则会出现“前端说合法、后端拒收”的体验断层
-
pattern在 Safari 中对某些 Unicode 字符支持不稳定,涉及中文、emoji 时建议额外加 JS 补充校验 - 移动端
type="tel"会唤起数字键盘,但它的校验能力几乎为零,必须配pattern才真正有效 - 不要把敏感逻辑(如密码强度、用户名查重)只放在前端,这些必须走服务端接口确认



















