autofocus在iOS Safari中静默失效是Apple设计限制,非bug;Android Chrome和微信WebView也趋严拦截,且仅在HTML初始解析时检查一次,SPA路由切换后动态挂载的input即使带autofocus也不触发。

autofocus在iOS Safari里静默失效是设计使然
不是bug,是Apple明确禁止非用户手势触发键盘弹出。哪怕源码写了autofocus,iOS Safari在页面加载、后台切前台、iframe内都会直接忽略。Android Chrome和微信WebView近年也趋严拦截,且只在HTML初始解析时检查一次——SPA路由切换后动态挂载的input,无论是否带autofocus,浏览器都不再扫描。
多个autofocus共存时只有第一个源码元素生效
HTML规范强制要求:同一文档中,仅第一个被解析到的autofocus元素触发聚焦,其余全部静默忽略。这跟渲染顺序、CSS显示状态、v-if条件无关,只取决于源码书写位置。
- 常见踩坑:
<dialog id="login"><input autofocus></dialog>和<dialog id="search"><input autofocus></dialog>同时存在 → 只有login里的input获得焦点 - SSR输出中已有
autofocus,客户端动态插入的新弹窗即使带该属性也无效 - 服务端返回含
autofocus的HTML片段,用innerHTML插入后照样不触发
React/Vue中必须用focus()替代autofocus,但得过四关
手动调用input.focus()是唯一可靠路径,但必须同步满足四个硬性条件,否则静默失败:
-
element.isConnected === true(已挂载到document) -
element.offsetParent !== null(未被display: none或visibility: hidden隐藏) -
element.tabIndex >= 0 && !element.disabled && !element.hasAttribute('inert')(可聚焦且未锁定) -
document.activeElement !== element(避免覆盖用户当前输入)
推荐统一用requestAnimationFrame(() => element.focus())延迟一帧,避开CSS transition未结束、DOM渲染未完成等时机问题。
立即学习“前端免费学习笔记(深入)”;
iOS Safari要求focus()必须在用户手势同步上下文中调用
单纯在useEffect或onMounted里裸调input.focus(),在iOS上大概率白忙活。必须确保它发生在click、touchstart、keydown等事件回调中。
- 模态框由按钮点击打开 → 在该按钮的
onClick或@click回调里立即调用input.focus() - SPA路由跳转后需聚焦 → 监听
popstate或框架路由afterEach钩子,并确认操作源自用户导航(如history.pushState是用户点击触发的) - 避免用
setTimeout或requestAnimationFrame绕过手势限制 —— iOS不认
真正容易被忽略的是:软键盘是否弹出 ≠ 元素是否获得焦点。iOS上常能focus()成功但键盘不弹,此时需额外引导用户点击,而非依赖自动行为。



















