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

如何处理输入框聚焦状态下内部按钮的交互问题?

解决密码输入框焦点与显示按钮的交互问题

这个问题的核心是点击按钮时输入框失去焦点,触发onBlur隐藏按钮,导致交互中断。下面提供几种可行的解决方法:

方法1:通过onBlur的relatedTarget判断焦点是否在内部

利用blur事件的relatedTarget属性,判断焦点是否转移到了同一个容器内的按钮上。只有当焦点完全离开整个输入容器时,才隐藏按钮。

修改后的代码:

<div className="input-wrapper">
  <input
    onFocus={() => setShowButton(true)}
    onBlur={(e) => {
      // 检查焦点是否转移到了容器内的按钮
      const isFocusingInside = e.currentTarget.closest('.input-wrapper').contains(e.relatedTarget);
      if (!isFocusingInside) {
        setShowButton(false);
      }
    }}
    title="password"
    type={type === 'password' && toggle ? 'text' : 'password'}
    {...props}
  />
  {showButton && (
    <button
      type="button"
      className={type === 'password' ? 'password' : ''}
      onClick={() => setToggle(!toggle)}
    >
      {toggle ? <ShowPasswordIcon /> : <HidePasswordIcon />}
    </button>
  )}
</div>

方法2:阻止按钮mousedown的默认行为

mousedown事件会在blur之前触发,阻止它的默认行为可以避免输入框失去焦点。这样点击按钮时,输入框保持焦点,按钮不会消失。

修改按钮部分:

<button
  type="button"
  className={type === 'password' ? 'password' : ''}
  onMouseDown={(e) => e.preventDefault()} // 阻止默认焦点转移
  onClick={() => setToggle(!toggle)}
>
  {toggle ? <ShowPasswordIcon /> : <HidePasswordIcon />}
</button>

方法3:用CSS :focus-within替代JS状态(更简洁)

不需要依赖React状态,直接通过CSS的:focus-within伪类控制按钮显示。只要容器内的输入框或按钮有焦点,按钮就会显示。

首先移除JS中的onFocus、onBlur和showButton状态:

<div className="input-wrapper">
  <input
    title="password"
    type={type === 'password' && toggle ? 'text' : 'password'}
    {...props}
  />
  <button
    type="button"
    className={`${type === 'password' ? 'password' : ''}`}
    onClick={() => setToggle(!toggle)}
  >
    {toggle ? <ShowPasswordIcon /> : <HidePasswordIcon />}
  </button>
</div>

然后添加CSS:

.input-wrapper .password {
  display: none; /* 默认隐藏按钮 */
}

.input-wrapper:focus-within .password {
  display: inline-block; /* 容器内有焦点时显示按钮 */
}

这种方法更符合原生交互逻辑,减少JS状态管理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:57:22