实时校验分三层:input中轻量格式初筛(如邮箱缺@),blur时延迟校验确保DOM更新(防下拉竞态),submit仅补业务规则漏洞(如订单号禁TEST);关键在时机、粒度与反馈精度的平衡。

实时校验不是等用户点提交才检查,而是输入过程中就反馈问题。关键在于平衡响应速度和判断准确性——太早校验(比如 input 事件里立刻查),容易误报;太晚(比如只靠 submit 拦截),又失去“实时”意义。
input 事件里做格式初筛,别做最终判定
用户每敲一个键都会触发 input 事件,适合做轻量级检查:比如邮箱缺 @、手机号位数不够、密码长度未达 6 位。但此时不能弹错、不能阻断操作,只该更新提示状态(如边框变红、显示“还需 2 位”)。
- 避免在
input里调用setCustomValidity()或reportValidity(),它们会干扰后续原生提交流程 - 不要用正则全量匹配复杂规则(如强密码:大小写+数字+符号),CPU 负担大,卡顿明显
- 对中文输入法的
compositionstart/compositionend无感处理,否则中文还没选字就报错
blur 事件是最终合法性兜底时机,但必须延迟执行
用户离开输入框时,blur 是确认“这段输入是否算完成”的自然节点。但直接在里面校验,会踩中动态下拉列表的竞态坑:点击列表项 → 触发 blur → 此时 input.value 还没被更新 → 校验失败。
- 必须用
setTimeout(() => { /* 校验逻辑 */ }, 0)把校验推到下一个宏任务,确保 DOM 更新完成 - 校验目标不是“是否为空”,而是“值是否在合法集合内”——比如比对原始
options数组,或检查data-value属性 - 若不合法,除了
alert(),更应调用input.focus()并阻止表单其他字段获得焦点(防止用户跳过)
submit 事件只做最后保险,不承担主校验职责
submit 是防线的最后一道闸门,但它不该是第一道。浏览器原生的 required、type="email" 等已在此阶段自动触发,你额外加的 JS 校验只是补漏。
立即学习“前端免费学习笔记(深入)”;
- 不要在
submit里重新跑一遍input阶段的格式检查,重复劳动且掩盖了实时反馈缺失的问题 - 重点补原生不覆盖的业务规则:比如“订单号不能以 TEST 开头”、“两个日期不能倒置”
- 调用
event.preventDefault()后,错误提示要明确指向具体字段(比如滚动到对应input并聚焦),而不是只弹个模糊提示
真正难的不是写校验逻辑,而是决定在哪一刻、以什么粒度、向用户传递哪一层信息。输入中提示格式,失焦时确认归属,提交前兜住业务漏洞——三层节奏一旦错位,用户就会觉得“这个表单总在跟我作对”。



















