blur 事件不可阻止,只能失焦后补救;应提前控制焦点转移,避免在 blur 中 focus() 导致闪烁或辅助技术失效;表单 submit/reset 后需手动聚焦;移动端软键盘收起不保证触发 blur,关键逻辑勿依赖它。

blur 是监听 input 失去焦点的正确事件,但直接绑定它常踩坑——比如在表单提交或重置后失焦不可控、移动端软键盘收起不触发、甚至 blur 中试图阻止失焦根本无效。
blur 事件本身不能被阻止,只能事后补救
blur 是浏览器强制行为,event.preventDefault() 在其中完全不起作用。所谓“防止失焦”,实际是失焦后立刻再调用 focus(),但这有明显副作用:
- 视觉闪烁,尤其在快速切换输入框时
- 破坏屏幕阅读器等辅助技术的焦点流
- 若在
blur回调里异步聚焦(如setTimeout),可能被用户下一次点击覆盖
更稳妥的做法是:提前控制焦点转移时机,而不是在 blur 里硬拉回来。
表单 submit/reset 后焦点自动丢失是标准行为
调用 form.submit() 或 form.reset() 会同步清空字段并移除焦点,这不是 bug,而是规范。修复方式需分场景:
- 对
submit:在event.preventDefault()后手动聚焦目标input,避免页面跳转干扰 - 对
reset:监听reset事件,在回调中加setTimeout(() => input.focus(), 0)—— 因为重置操作虽同步,但 DOM 更新可能有微小延迟 - 用
react-hook-form等库时,查文档确认是否有onReset钩子,别直接操作 DOM
移动端软键盘收起 ≠ blur,很多机型根本不触发
iOS Safari 和部分安卓 WebView 对软键盘收起是否触发 blur 没有统一策略。常见误判是:用户输完就关键盘,结果 blur 没执行,校验逻辑卡住。
- 不要依赖
blur做关键校验或提交,改用input+ 防抖 - 若必须响应“结束输入”,可结合
focusout(冒泡版blur)+document.activeElement判断是否真离开了输入框 - 动态插入的
input(如模态框内),别信autofocus,改用框架安全钩子(如 Bootstrap 的shown.bs.modal或 React 的useEffect)
focus() 调用失败的四个硬性前提
想让 input.focus() 生效,必须同时满足:
-
document.activeElement不是当前元素 → 先判断if (input && document.activeElement !== input) - 元素未被
display: none或visibility: hidden隐藏 → 检查getComputedStyle(input).display !== 'none' - 调用发生在用户手势上下文内(如
click、touchend、keydown)→ AJAX 回调或定时器中调用会被 iOS Safari 静默拦截 - 元素已挂载到 DOM,且
tabindex设置合理 → 原生input默认可聚焦;若用div模拟,必须设tabindex="0",不能是-1
最易忽略的是第三点:非手势上下文中调用 focus() 在移动端基本失效,且无报错,只能靠日志或调试器确认是否进入执行分支。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











