autofocus 属性仅在页面首次加载时生效一次,且仅支持可聚焦元素:input(非hidden)、textarea、select、button及带tabindex的元素;div或span需设tabindex="0"才有效,与JS focus()方法有本质区别。

autofocus 属性本身很简单,但实际用起来常被忽略兼容性、焦点抢占和可访问性问题。它只在页面首次加载时生效一次,且不能通过 JS 反复触发。
哪些元素支持 autofocus
只有可聚焦的表单控件原生支持:input(type 不为 hidden)、textarea、select、button,以及带 tabindex 的任意元素(但此时需手动加 autofocus 才有效)。div 或 span 直接加 autofocus 属性无效。
常见错误现象:<div autofocus>xxx</div> 页面加载后毫无反应 —— 因为 div 默认不可聚焦,必须同时设 tabindex="0"。
-
<input type="text" autofocus>✅ 有效 -
<input type="hidden" autofocus>❌ 无效(hidden输入框不可聚焦) -
<div tabindex="0" autofocus>✅ 有效 -
<div autofocus>❌ 无效
autofocus 和 focus() 的区别在哪
autofocus 是 HTML 属性,由浏览器在解析 DOM 时自动处理;focus() 是 JS 方法,需手动调用,且可重复执行。两者行为不等价。
关键差异:
-
autofocus只在页面初始加载时起作用,后续路由跳转或 DOM 重绘不会再次触发 -
focus()可在任意时机调用,但若目标元素未渲染完成或被display: none隐藏,会静默失败 -
autofocus会绕过部分屏幕阅读器的焦点管理逻辑,可能影响可访问性;focus()配合setTimeout或requestAnimationFrame更可控
例如单页应用中,想在某个 modal 打开后聚焦输入框,必须用 JS:
document.getElementById('search-input').focus();
容易被忽略的兼容性和干扰点
Chrome、Firefox、Safari 均支持 autofocus,但 iOS Safari 在页面从后台切回前台时,可能忽略该属性;某些 Android WebView 也存在类似限制。
更隐蔽的问题是焦点抢占:
- 如果页面有多个
autofocus元素,只有第一个会被聚焦(规范行为,但容易误以为“没生效”) - 某些框架(如 Vue、React)服务端渲染后客户端 hydrate,可能导致
autofocus在 SSR 阶段被忽略,需改用ref+focus() - 密码管理器插件、翻译扩展等可能劫持焦点,导致
autofocus失效且无报错
建议:对关键交互场景(如登录页首输入框),优先用 JS 显式聚焦,并加简单容错:
if (input && document.activeElement !== input) { input.focus(); }
真正要注意的是:别假设 autofocus 一定成功,尤其在混合渲染、多 tab 切换或辅助技术环境下。它的价值在于简化静态页面的默认行为,而不是替代 JS 焦点控制逻辑。

















