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

点击Calendar组件图标时输入框失焦的问题解决咨询

解决输入框点击日历图标失焦的问题

问题背景

已实现功能:点击输入框时显示Calendar组件,点击输入框外部时隐藏该组件。
当前问题:点击Calendar组件内的图标时,输入框会失去焦点,导致Calendar组件被隐藏,无法正常操作日历功能。

解决方案

方法一:容器范围判断 + 事件冒泡阻止

核心思路是通过容器Ref判断点击区域是否属于输入框或Calendar组件,同时阻止图标点击事件的冒泡,避免触发不必要的失焦逻辑。

修改父组件代码

import { useState, useRef } from 'react';

// ...其他业务代码

const [isFocused, setIsFocused] = useState(false);
// 获取输入框和Calendar的父容器Ref
const inputContainerRef = useRef(null);

const handleBlur = () => {
  // 延迟判断,确保点击事件先完成
  setTimeout(() => {
    // 检查当前活跃元素是否在容器内,不在则隐藏Calendar
    if (!inputContainerRef.current?.contains(document.activeElement)) {
      setIsFocused(false);
    }
  }, 0);
};

<form onSubmit={addTask}>
  <div ref={inputContainerRef}>
    <input
      id="task"
      placeholder=' Add task to "Inbox" on "Tomorrow"'
      className={styles.input}
      onChange={handleChange}
      value={taskName}
      onFocus={() => setIsFocused(true)}
      onBlur={handleBlur}
    ></input>
    {isFocused && <Calendar />}
  </div>
</form>

修改Calendar组件代码

const Calendar = () => {
  const [isShown, setIsShown] = useState(false);

  const clickIcon = (e) => {
    e.preventDefault();
    e.stopPropagation(); // 阻止事件冒泡,避免触发父元素的失焦相关逻辑
    setIsShown((current) => !current);
  };

  return (
    <div>
      <CalendarMonthIcon
        onClick={clickIcon}
        className={styles.calendar}
      ></CalendarMonthIcon>
      {isShown && <Datepicker />}
    </div>
  );
};

方法二:Mousedown标记法

利用mousedown事件在blur之前触发的特性,设置标记忽略本次失焦。

修改父组件代码

const [isFocused, setIsFocused] = useState(false);
// 标记是否忽略本次失焦
let ignoreBlur = false;

const handleCalendarMousedown = () => {
  ignoreBlur = true;
};

const handleBlur = () => {
  if (!ignoreBlur) {
    setIsFocused(false);
  }
  // 重置标记,不影响后续操作
  ignoreBlur = false;
};

<form onSubmit={addTask}>
  <div>
    <input
      id="task"
      placeholder=' Add task to "Inbox" on "Tomorrow"'
      className={styles.input}
      onChange={handleChange}
      value={taskName}
      onFocus={() => setIsFocused(true)}
      onBlur={handleBlur}
    ></input>
    {isFocused && <Calendar onMousedown={handleCalendarMousedown} />}
  </div>
</form>

修改Calendar组件代码

const Calendar = ({ onMousedown }) => {
  const [isShown, setIsShown] = useState(false);

  const clickIcon = (e) => {
    e.preventDefault();
    setIsShown((current) => !current);
  };

  // 在Calendar容器上绑定mousedown事件,设置忽略失焦标记
  return (
    <div onMouseDown={onMousedown}>
      <CalendarMonthIcon
        onClick={clickIcon}
        className={styles.calendar}
      ></CalendarMonthIcon>
      {isShown && <Datepicker />}
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:15:30