chrome 表单提交时报“an invalid form control with name='' is not focusable”错误,源于带 required 的控件为空且不可聚焦(如 display: none),修复需同步隐藏、移除 required、清空值三步。

Chrome 提交时报 An invalid form control with name='' is not focusable
这是 Chrome(及部分基于 Chromium 的浏览器)在表单提交时的真实报错,不是 JS 异常,不进 console,只出现在 DevTools 的 Console 标签页顶部红色横幅里。它意味着:某个带 required 的控件为空,且当前不可聚焦(比如 display: none 或 visibility: hidden),浏览器想弹提示却找不到焦点目标。
关键点在于:这个错误和你有没有显式写 required 无关——只要该 input 满足两个条件,就会被校验:
① DOM 中存在(没被 remove())
② required 属性为 true(包括动态设为 true、或初始 HTML 就带)
- 即使你用 JS 隐藏了它,只要没同步清理状态,它仍参与校验
-
opacity: 0或position: absolute; left: -9999px不触发该报错(元素仍可聚焦) - 用
disabled会跳过校验,但字段值不会提交;用aria-hidden="true"仅影响读屏器,不影响校验
隐藏 input 时 required 状态没同步导致静默失败
常见于“其他”选项展开场景:选中 radio 后显示文本框并设 textBox.required = true,但取消选择时只隐藏元素,没改 required 或清空值。结果表单提交被拦截,页面无反应,控制台也没报错——因为浏览器直接阻止了 submit 事件,连 invalid 事件都不发。
修复必须同步三件事:
- 视觉隐藏 →
textBox.style.display = 'none' - 校验解除 →
textBox.required = false(或textBox.removeAttribute('required')) - 值清空 →
textBox.value = ''(避免残留值干扰后续逻辑)
漏掉任意一项,都可能让表单卡住。尤其注意:仅设 required = false 不够,如果值非空,某些浏览器仍会尝试校验(取决于内部实现)。
form.submit() 调用绕过 required 校验但报错仍出现
用 JS 主动调用 form.submit() 本身不会触发原生 required 校验,但如果你之前已监听 submit 并 preventDefault(),又没手动调 reportValidity(),就可能出现两种矛盾现象:
— 表单没提交(你以为是 JS 错误)
— 控制台却冒出 An invalid form control...(其实是上一次用户点击 submit 按钮触发的遗留校验)
根本原因是:浏览器对每个 submit 事件独立执行校验流程。哪怕你 preventDefault() 了,它仍会检查所有 required 字段是否可聚焦。
- 正确做法:在
submit处理函数里,先调event.target.reportValidity(),仅返回true时才继续后续逻辑 - 避免混用:不要一边
preventDefault(),一边又依赖原生校验气泡;要么全交给浏览器,要么全自己 handle -
form.checkValidity()返回false时,不代表一定有该报错——它只说明有无效字段,但是否聚焦失败,得看字段是否可见
移动端 Safari 对 hidden required 字段的兼容性差异
iOS Safari(特别是 15.4 之前版本)对 display: none + required 的处理更宽松:它可能跳过校验,不报错也不阻止提交。但这不是修复,是 bug 行为——上线后 Chrome 用户就会遇到问题,而你本地测不出来。
真正跨端稳定的方案只有一条:视觉隐藏和校验状态必须严格绑定。不要依赖“Safari 没报错所以没问题”。
- 别用
visibility: hidden替代display: none—— 它同样导致聚焦失败 - 别指望
novalidate解决问题 —— 它禁用全部原生校验,但你的业务逻辑可能仍需验证 - 动态字段(如多步表单)建议用
fieldset包裹,并配合disabled控制整组校验开关,比单个input更易维护
最易被忽略的细节是:隐藏动作和 required 状态变更必须在同一个执行上下文完成,不能靠 setTimeout 或异步回调延迟处理——否则中间窗口期就可能触发校验。











