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

React FullCalendar如何禁用指定节假日单元格的点击功能?

FullCalendar 节假日单元格禁用失效问题解决

问题背景

我有一个存储节假日信息的数组:

const publicholidays = [
  { title: "Republic Day", date: "2023-01-26", backgroundColor: "grey" },
  { title: "Maudy Thursday", date: "2023-04-06", backgroundColor: "grey" },
  { title: "Good Friday", date: "2023-04-07", backgroundColor: "grey" },
  { title: "Ramzan", date: "2023-04-21", backgroundColor: "grey" },
  { title: "May Day", date: "2023-05-01", backgroundColor: "grey" },
  { title: "Bakri Id", date: "2023-07-04", backgroundColor: "grey" },
  { title: "Independence Day", date: "2023-08-15", backgroundColor: "grey" },
  { title: "1st Onam", date: "2023-08-28", backgroundColor: "grey" },
  { title: "Thiruonam", date: "2023-08-29", backgroundColor: "grey" },
  { title: "Gandhi Jayanthi", date: "2023-10-02", backgroundColor: "grey" },
  { title: "Vijaya Dashami", date: "2023-10-24", backgroundColor: "grey" },
  { title: "Christmas Day", date: "2023-12-25", backgroundColor: "grey" },
  { title: "Christmas Day", date: "2023-12-26", backgroundColor: "grey" },
];

想要禁用这些日期对应的日历单元格点击功能,写了下面的函数并通过dayCellContent={disableHolidays}调用,但单元格未被禁用还出现错误:

const disableHolidays = (info) => {
  debugger
  const dateStr = info.date.toISOString().slice(0,10); // Get the date string of the current day cell
  const holiday = publicholidays.find(holiday => holiday.date === dateStr); // Check if the current day cell is a holiday
  if (holiday) {
    const cell = info.el?.querySelector('.fc-daygrid-day-content');
    cell.classList.add('disabled'); // Add a CSS class to the day cell to make it disabled
    // Disable the click event on the day cell
    cell.onclick = function() {
      return false;
    };
  }
};

问题原因

  1. 钩子使用错误:dayCellContent的核心作用是自定义单元格内的文本/内容,而非修改单元格交互。在此钩子中操作DOM会被FullCalendar的内部渲染逻辑覆盖,导致修改失效。
  2. 事件绑定无效:直接给cell.onclick赋值无法阻止FullCalendar本身的点击事件——FullCalendar的事件监听优先级更高,且这种方式并非官方推荐的禁用交互方案。
  3. DOM元素选择偏差:点击事件实际绑定在.fc-daygrid-day容器上,而非内部的.fc-daygrid-day-content元素,你选择的DOM元素并非事件触发的目标。

解决方案

方法一:使用官方配置selectAllow(推荐)

如果需求是禁用日期选择功能(比如点击创建事件、跳转等),直接用FullCalendar提供的selectAllow配置项,无需手动操作DOM:

const calendarOptions = {
  // 其他原有配置
  selectable: true, // 先开启可选功能
  selectAllow: (selectInfo) => {
    const dateStr = selectInfo.start.toISOString().slice(0, 10);
    // 非节假日才允许选择
    return !publicholidays.some(holiday => holiday.date === dateStr);
  },
  // 同时给节假日单元格添加样式
  dayCellClassNames: (info) => {
    const dateStr = info.date.toISOString().slice(0, 10);
    return publicholidays.some(holiday => holiday.date === dateStr) 
      ? 'disabled-holiday' 
      : '';
  }
};

配套CSS样式:

.disabled-holiday {
  background-color: grey;
  pointer-events: none; /* 彻底阻止点击 */
  opacity: 0.7;
  cursor: not-allowed;
}

方法二:用dayCellDidMount钩子操作DOM

如果需要更灵活的自定义交互,使用dayCellDidMount钩子——它会在单元格完全挂载后触发,不会被渲染逻辑覆盖:

const disableHolidays = (info) => {
  const dateStr = info.date.toISOString().slice(0, 10);
  const isHoliday = publicholidays.some(holiday => holiday.date === dateStr);
  if (isHoliday) {
    const dayCell = info.el; // 获取整个单元格容器
    dayCell.classList.add('disabled-holiday');
    // 阻止点击事件的传递和默认行为
    dayCell.addEventListener('click', (e) => {
      e.preventDefault();
      e.stopPropagation();
    });
  }
};

// 配置FullCalendar时使用该钩子
const calendarOptions = {
  // 其他原有配置
  dayCellDidMount: disableHolidays
};

同样使用上述disabled-holiday的CSS样式即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:17:45