autofocus在弹窗中无效,因浏览器仅在初始html解析时识别;应通过监听弹窗就绪事件或在用户手势同步上下文中调用focus()实现自动聚焦。

autofocus在弹窗里根本不会触发,不是你写错了
弹窗(<dialog></dialog>、v-if条件渲染、React useState控制显隐)里的 autofocus 属性基本无效——浏览器只在初始 HTML 解析时扫描一次,而弹窗 DOM 是后来动态插入的,autofocus 被完全忽略。这不是 bug,是规范行为。
常见错误现象包括:<dialog><input autofocus></dialog> 打开后光标没进输入框;Vue/React 组件里写了 autofocus 却毫无反应;多个弹窗共存时只有第一个有焦点。
- 删掉所有弹窗内的
autofocus属性,它在这里纯属干扰项 - 确保弹窗 DOM 已真实挂载(比如
v-if="show"为true后再操作) - 不要依赖
dialog.showModal()自动触发聚焦——它不重评估autofocus
手动 focus() 必须等 DOM 可见且可聚焦
调用 input.focus() 不等于“一定成功”,它会静默失败(不报错),尤其当目标元素还处于 transition 动画中、父容器 opacity: 0、visibility: hidden 或被 inert 锁住时。
正确做法是监听弹窗真正“就绪”的时机,而不是一打开就急着 focus():
- 对原生
<dialog></dialog>,监听dialog.addEventListener('focusin', handler, { once: true }),在 handler 中聚焦目标元素 - React 中用
useEffect(() => { ref.current?.focus(); }, [isOpen]),且isOpen必须是弹窗显示状态的精确反映 - Vue 中在
onMounted+v-if为真后调用inputRef.value?.focus(),不能放在onBeforeMount - 异步加载内容的弹窗(如带
await的数据请求),需等渲染完成,可用requestAnimationFrame(() => ref.current?.focus())
iOS Safari 下 focus() 必须绑定在用户手势中
iOS Safari 主动拦截非用户直接触发的 focus(),哪怕你在 click 回调里调用 showModal() 再立刻 focus(),只要中间夹了任何异步逻辑(比如 Promise.then、setTimeout、甚至 requestAnimationFrame),键盘大概率不弹。
可靠写法只有一种:把 focus() 放在原始点击事件的同步执行栈里:
button.addEventListener('click', () => { dialog.showModal(); input.focus(); })- React 中
onClick={() => { setShow(true); setTimeout(() => inputRef.current?.focus(), 0); }}❌ 失效 - 正确写法:
onClick={() => { setShow(true); inputRef.current?.focus(); }}(前提是inputRef.current此刻已存在且可见) - 若输入框是条件渲染的,需先强制渲染(如用
forceUpdate或拆分 state),再同步focus()
多弹窗嵌套时焦点别被抢走
弹窗 A 还开着,再打开弹窗 B,B 的输入框聚焦后,A 关闭时若没清理焦点,document.activeElement 可能仍指向 A 里的旧元素,导致 Tab 键跳转异常或焦点丢失。
必须在弹窗关闭逻辑中主动释放焦点:
- 监听
dialog.close或keydown(Esc)事件,在回调里执行input.blur()或document.body.focus() - 避免在
blur回调里立即focus()到另一个元素,容易触发循环或被浏览器拦截 - 多个弹窗共存时,不要靠 DOM 顺序或渲染先后判断“谁该聚焦”,而是按当前最高层弹窗的
isOpen状态做唯一判断 - 检查元素是否满足聚焦前提:
disabled是否已移除、tabindex是否 ≥ 0、父级是否含inert
focus() 写在 click 回调最末尾,如果这个弹窗是通过路由跳转间接触发的(比如点击菜单 → router.push → 页面组件 useEffect 显示弹窗),整个链路已脱离原始手势上下文,focus() 就成了摆设。这时候只能退回到按钮点击那一刻同步聚焦,或者接受“首次不自动聚焦,用户点一下再聚焦”的体验妥协。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











