autofocus仅对text、search、email输入框及textarea稳定生效,select和button支持有限,hidden、checkbox、disabled元素及不可见/不可聚焦元素均无效;其失效主因是动态渲染、ios限制或dom不可见,应改用js显式focus()。

autofocus 属性在绝大多数实际场景中都不该直接依赖——它只在页面初始 HTML 解析时起一次作用,之后完全失效。纯静态页可试,但只要涉及动态渲染、SPA、模态框、iOS Safari 或用户手势上下文,就必须改用 JS 显式调用 .focus()。
autofocus 只对哪些元素生效?
它不是“写上就聚焦”,而是有严格类型和状态限制:
-
<input type="text">、<input type="search">、<input type="email">、<textarea></textarea>✅ 稳定支持 -
<select></select>⚠️ Chrome/Edge 行为一致,Firefox 和旧版 Safari 明确不支持(错误信息:autofocus is not supported on <select></select>) -
<button></button>⚠️ 大部分浏览器支持,但 iOS Safari 偶尔跳过 -
<input type="hidden">、<input type="checkbox">、<input disabled>、<div autofocus> ❌ 静默忽略,不报错 <li>父容器含 <code>display: none、visibility: hidden、inert或自身tabindex="-1"→ 直接跳过 - DOM 是 JS 动态插入的(比如
innerHTML = '...autofocus...'),解析已完成,属性无效 - Vue/React 中写
<input autofocus>,SSR 渲染后 hydration 时 DOM 已存在,错过解析时机 - 模态框初始
display: none,之后 JS 切成block→ 解析时不可见,属性被丢弃 - iOS Safari 主动限制非用户手势触发的聚焦,防止软键盘意外弹出;页面从后台切回时也常静默忽略
- 多个
autofocus元素 → 浏览器只聚焦第一个(按源码顺序),其余全忽略 - 原生 JS:监听
DOMContentLoaded后检查document.activeElement !== input,再调input.focus() - React:用
useEffect(() => { inputRef.current?.focus() }, []),并加if (typeof window !== 'undefined')防 SSR 报错 - Vue 3:在
onMounted中调inputRef.value?.focus(),确保v-if已为true - iOS 安全方案:绑定一次
click或touchstart到按钮或body,回调中立即调input.focus() - 加防护:聚焦前校验元素是否可见、可聚焦、未被禁用;推荐加
.focus({ preventScroll: true })避免页面滚动 - 密码管理器插件、翻译扩展可能劫持焦点,导致失效且无报错
- 屏幕阅读器用户可能被突然聚焦打断信息接收,WCAG 建议配合
aria-describedby提前说明 - 移动端软键盘过早弹出会遮挡内容,尤其首屏非输入型页面(如新闻页顶部搜索框)
-
autofocus不触发focus事件(聚焦发生在事件循环之前),而.focus()会,调试时注意这点
为什么写了 autofocus 却没反应?
常见失效原因不是代码写错,而是浏览器根本没机会处理它:
替代方案:用 JS 手动 focus() 更可靠
关键不是“能不能调”,而是“什么时候调、要不要调”:
容易被忽略的兼容性与干扰点
真正要注意的是:别假设 autofocus 一定成功,尤其在混合渲染、多 tab 切换或辅助技术环境下:











