focusin 比 focus 更可靠,能捕获所有聚焦来源(包括 autofocus、JS focus()、点击图标等),且冒泡支持父容器统一监听;focus 不冒泡且不响应程序化聚焦,iOS Safari 还忽略 autofocus。

onfocus 是最直接的监听方式,但它只在用户主动点击或按 Tab 进入时触发,不响应 autofocus 属性或 JS 调用 .focus() 后的“程序化聚焦”——后者需额外监听 focusin 才能捕获。
focus 事件不触发?检查是否被 autofocus 或 JS 覆盖
页面加载后 input 没有执行 onfocus 回调,大概率是因为:autofocus 属性虽让元素获得焦点,但不会触发 focus 事件(规范明确要求);同理,JS 中调用 input.focus() 若发生在 DOM 尚未可交互阶段(如 DOMContentLoaded 前),也可能静默失败。
- 确保绑定监听在
DOMContentLoaded或框架的挂载钩子(如 Vue 的onMounted、React 的useEffect(() => {}, []))之后 - 若用了
autofocus,又想统一处理聚焦逻辑,改用focusin事件——它冒泡且能捕获所有来源的聚焦(包括autofocus和.focus()) - 移动端 iOS Safari 对
autofocus几乎总是忽略,别依赖它来触发业务逻辑
focusin 比 focus 更可靠,尤其在动态场景下
focusin 是冒泡事件,focus 不冒泡。这意味着你可以把监听器挂在父容器上,一次绑定覆盖多个输入框,也更容易捕获由图标点击、按钮联动等间接触发的聚焦。
- 用
focusin替代focus:它会在元素真正获得焦点时触发,无论来源是鼠标、键盘、JS 还是autofocus - 注意:IE9+ 支持
focusin,但旧版 IE 需用focus+attachEvent兼容写法(现基本可忽略) - 避免在
focusin处理器里立即调用input.select()或弹出软键盘——部分安卓 WebView 会因时机过早导致异常
点击搜索图标也要触发聚焦?别只靠 CSS :focus
常见布局中,搜索图标用 <button> 或 <img> 绝对定位在 input 右侧,此时点击图标本身不会让 input 获得焦点——因为图标不是可聚焦元素,也无法通过 :focus 伪类联动样式。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
- 给图标容器(如
<button class="search-btn">)加tabindex="0",使其可聚焦 - 在 JS 中监听该按钮的
click或focusin,然后显式调用input.focus() - 如果要用纯 CSS 实现展开效果,必须让图标和
input是相邻兄弟关系,并用.search-btn:focus ~ .search-input规则——但这无法触发 JS 逻辑,仅限样式控制
focus 事件里不能做的事
聚焦瞬间不适合做重操作,尤其是涉及 DOM 修改、网络请求或第三方 SDK 初始化。浏览器可能尚未完成焦点切换动画,或正忙于软键盘调度,强行操作易导致状态错乱。
- 不要在
focus回调里调用input.select()后立刻document.execCommand('selectAll')(已废弃且不可靠) - 避免同步发起 API 请求——用户可能刚点进来就切走了,造成无效请求
- 若需清空提示文案或高亮边框,优先用 CSS
:focus-within或:focus类控制,JS 仅作补充 - 特别注意中文输入法场景:聚焦后用户可能立刻进入拼音组合状态,此时
input.value还是空的,别误判为“未输入”
真正容易被忽略的是:聚焦事件本身不携带“这次聚焦是否来自用户操作”的元信息。你无法区分是用户点了 input,还是 JS 脚本调了 .focus(),更无法知道是不是自动填充触发的——这些边界情况必须靠业务层埋点或状态标记来补全。


















