表单校验失败后需三步联动:先手动遍历筛选首个校验失败且可验证的控件,再在用户手势上下文中聚焦并保障键盘弹出,最后滚动至可视区中心,确保用户一眼看到、点到、改到错误项。

表单校验失败后,只显示红框或提示气泡是不够的——用户需要立刻看到、点到、改到错误项。关键不是“有没有报错”,而是“能不能一眼找到第一个错在哪”。这需要三步联动:找错、聚焦、滚动。
准确找出第一个校验失败的输入框
别依赖 form.checkValidity(),它只返回 true 或 false;也别用 :invalid 伪类选择器,它可能匹配到未渲染完成或被隐藏的元素。稳妥做法是手动遍历并筛选:
- 用
form.querySelectorAll('input, select, textarea')获取所有候选控件 - 跳过
disabled、type="hidden"和!el.willValidate的元素(后者排除掉没设任何校验规则的字段) - 对每个剩余元素检查
!el.validity.valid && el.willValidate,优先关注validity.valueMissing(必填未填)和validity.typeMismatch(如邮箱格式错),这两个最常见也最该优先响应 - 取第一个满足条件的元素,就是你要聚焦的目标
聚焦时确保键盘真正弹出(尤其在移动端)
单纯调 input.focus() 在 iOS Safari 或部分安卓 WebView 中常静默失败——浏览器策略禁止非用户手势触发的软键盘弹出。必须加一层“用户上下文”保障:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 如果是在用户点击提交按钮后校验,直接在该
click或touchstart回调里调用input.focus() - 如果校验是异步的(比如先发请求校验手机号是否已注册),先临时给输入框加
readonly属性,再focus(),再立即移除readonly - 避免在
fetch.then、setTimeout或滚动事件回调中直接focus(),大概率被拦截 - 聚焦后可加
input.select()(用setTimeout(() => input.select(), 0)防竞争),让光标更明显
滚动到可视区,别让用户自己找
只聚焦不滚动,等于没聚焦。很多错误输入框藏在折叠区域、导航栏下方或长表单底部,用户根本看不到。务必成对使用:
立即学习“前端免费学习笔记(深入)”;
- 先执行
input.focus(),再调input.scrollIntoView({ block: 'center' })——顺序不能反,否则可能失焦导致滚动失效 - 用
{ block: 'center' }而非默认值,防止被顶部 fixed 导航栏遮挡 - 若父容器有
overflow: hidden或transform,scrollIntoView可能失效,需手动计算位置并调window.scrollTo() - 老安卓 WebView 兼容性差时,可降级为
input.scrollIntoViewIfNeeded?.()或自行实现简易滚动逻辑
整个过程不需要第三方库,纯原生 JS 就能稳稳落地。核心是把“找错→聚焦→滚动”当作一个原子操作,而不是三个孤立步骤。


















