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

如何让CSS Grid周历的空白单元格可点击并获取时间与星期?

解决方案

方法一:事件委托+坐标计算获取时间与星期

直接在最外层Grid容器上绑定点击事件,通过点击位置的坐标计算出对应的星期和时间:

  1. 给最外层的.grid.flex-auto容器添加onClick事件监听
  2. 点击时通过getBoundingClientRect()获取容器与点击点的坐标关系,分别计算行列索引,映射到具体的星期和时间

示例代码(React环境):

const handleCalendarClick = (e) => {
  const gridContainer = e.currentTarget;
  const rect = gridContainer.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  // 计算星期:按7列划分,根据水平占比确定列索引
  const colIndex = Math.floor((x / rect.width) * 7);
  const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; // 可根据你的列顺序调整
  const targetDay = weekDays[colIndex];

  // 计算时间:按48行(每半小时一行)划分,转换为具体时间格式
  const rowIndex = Math.floor((y / rect.height) * 48);
  const hour = Math.floor(rowIndex / 2);
  const minute = rowIndex % 2 === 0 ? '00' : '30';
  const period = hour < 12 ? 'AM' : 'PM';
  const displayHour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
  const targetTime = `${displayHour}:${minute} ${period}`;

  // 打开Dialog并传入数据
  // openDialog({ day: targetDay, time: targetTime });
};

// 绑定事件到最外层容器
<div className="grid flex-auto grid-cols-1 grid-rows-1" onClick={handleCalendarClick}>
  {/* 原有周历结构 */}
</div>

方法二:重构单元格结构,携带数据属性

重新构建一个覆盖整个周历的单元格网格,每个空白单元格通过data-*属性直接存储对应的星期和时间,点击时直接读取:

  1. 生成7列×48行的单元格网格,每个单元格对应一个时间点+星期组合
  2. 给每个单元格添加data-day和data-time属性,绑定点击事件读取数据

示例代码(React环境):

// 生成时间槽数据:48条对应24小时的每半小时
const timeSlots = Array.from({ length: 48 }, (_, i) => {
  const hour = Math.floor(i / 2);
  const minute = i % 2 === 0 ? '00' : '30';
  const period = hour < 12 ? 'AM' : 'PM';
  const displayHour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
  return `${displayHour}:${minute} ${period}`;
});
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];

const handleCellClick = (e) => {
  const targetDay = e.target.dataset.day;
  const targetTime = e.target.dataset.time;
  // 打开Dialog并传入数据
  // openDialog({ day: targetDay, time: targetTime });
};

// 渲染覆盖式单元格网格,放在原有结构同一层级
<div className="col-start-1 col-end-2 row-start-1 grid grid-cols-7 grid-rows-48">
  {weekDays.map((day, colIdx) => (
    timeSlots.map((time, rowIdx) => (
      <div
        key={`${colIdx}-${rowIdx}`}
        className="cursor-pointer"
        data-day={day}
        data-time={time}
        onClick={handleCellClick}
      />
    ))
  ))}
</div>

注意事项

  • 方法一要注意容器尺寸计算的准确性,避免滚动、缩放导致坐标偏差
  • 方法二的单元格网格需设置合适的层级,避免遮挡原有事件组件的交互
  • 可根据你的周历星期起始顺序,调整weekDays数组的排列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:35:41