You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅在目标元素未处于当前聚焦状态时对其执行focus操作?

问题根因

你遇到的判断失效、输入框重复聚焦的核心原因是DOM事件的触发顺序:mousedown → 浏览器默认修改activeElement → mouseup → click。点击图标时,mousedown阶段浏览器检测到图标不属于可聚焦元素,会先把当前焦点转移到body,等执行click事件内的判断逻辑时,document.activeElement已经被修改为body,所以判断条件永远成立,导致输入框被重复聚焦,触发不必要的过渡动画。

最简解决方案

不需要引入额外状态和副作用,直接把图标绑定的onClick事件替换为onMouseDown,同时阻止浏览器默认的焦点转移行为即可:

onMouseDown={(e) => {
  // 阻止默认行为,避免activeElement被自动修改为body
  e.preventDefault();
  if (document.activeElement !== inputEl.current) {
    inputEl.current.focus();
  }
}}

这个方案不会出现先失焦再聚焦的情况,过渡动画仅会在输入框首次聚焦时触发,符合你的需求。

状态方案可行性说明

你设想的用状态记录聚焦状态、useEffect监听失焦重置的方案是可运行的,但属于非必要的复杂实现:需要额外引入状态依赖,还要手动绑定、清理聚焦/失焦监听事件,维护成本更高,也存在状态同步异常的潜在风险,除非有特殊场景必须使用click事件,否则不优先推荐。如果确实需要用该方案,参考实现如下:

const [isInputFocused, setIsInputFocused] = useState(false);

useEffect(() => {
  const input = inputEl.current;
  if (!input) return;
  const handleFocus = () => setIsInputFocused(true);
  const handleBlur = () => setIsInputFocused(false);
  input.addEventListener('focus', handleFocus);
  input.addEventListener('blur', handleBlur);
  return () => {
    input.removeEventListener('focus', handleFocus);
    input.removeEventListener('blur', handleBlur);
  };
}, []);

onClick={() => {
  if (!isInputFocused) {
    inputEl.current.focus();
  }
}}

内容的提问来源于stack exchange,提问作者embracethefuture

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:36:00