必须用 input 事件配合 setcustomvalidity('') 实时清空并重设校验状态,oninvalid 仅提交时触发且不可控,ios safari 需额外处理 focusout 和 submit 兜底。

不能靠 required 属性本身改提示文案,浏览器原生提示(如“请填写此字段”)完全不可控;真正能自定义的只有 setCustomValidity(),但它必须配合事件监听和状态清空才有效。
oninvalid 事件只在提交时触发,不是实时校验入口
oninvalid 确实能捕获校验失败,但它的触发时机非常有限:仅在表单 submit 或显式调用 reportValidity() 时发生。用户输入过程中它根本不会响,所以不能把它当“实时反馈钩子”来用。
- 单独写
oninvalid="alert('')"会导致原生提示和弹窗同时出现,体验混乱 - IE10+ 支持该事件,但旧版 IE 完全不支持,得降级处理
- 它不解决“用户输对了还报错”的问题——因为错误状态没被清空
setCustomValidity() 必须配 input 事件清空,否则校验卡死
setCustomValidity() 不是“设完就显示”,而是给 input 打上一个“我错了”的标记。一旦传入非空字符串(比如 setCustomValidity('邮箱不能为空')),这个标记就会一直挂着,哪怕用户已经填对了,checkValidity() 仍返回 false。
- 清空必须用严格空字符串
setCustomValidity(''),传null、undefined或空格都会变成字符串字面量,反而锁死验证 - 最可靠的位置是
input事件里:每次按键、粘贴、删除都触发,覆盖右键粘贴、语音输入等场景 - 别用
onkeyup:它漏掉粘贴;也别只靠onchange:用户可能永远不离开输入框
移动端 iOS Safari 的 onBlur 失效问题
iOS Safari 点击键盘「完成」按钮后,blur 事件经常不触发,导致错误提示卡住不消失。这不是 bug,是系统级行为。
- 必须同时监听
input和focusout(或touchend后延时补调) - 不要依赖“失焦即校验”的单一路径;表单提交前务必再调一次
form.checkValidity()做兜底 - 如果用了
reportValidity()主动弹提示,iOS 上建议统一放在form.submit事件里处理,比按钮click更稳
复杂校验要手动读 validity 对象,别无脑设同一文案
一个 input 同时有 required、pattern、min 等多个约束时,oninvalid 触发不代表你该统一说“格式错误”。用户需要知道具体哪条没过。
- 检查
input.validity.valueMissing→ 是空值未填 - 检查
input.validity.patternMismatch→ 正则不匹配 - 检查
input.validity.rangeUnderflow→ 小于min - 每次校验前先
setCustomValidity(''),再根据具体分支设对应文案
最容易被忽略的其实是清空那句 setCustomValidity('') —— 它必须出现在每一次输入变化中,哪怕你还没开始做逻辑判断。漏掉它,整个校验流程就从第一次失败起彻底失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











