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; }; } };
问题原因
- 钩子使用错误:
dayCellContent的核心作用是自定义单元格内的文本/内容,而非修改单元格交互。在此钩子中操作DOM会被FullCalendar的内部渲染逻辑覆盖,导致修改失效。 - 事件绑定无效:直接给
cell.onclick赋值无法阻止FullCalendar本身的点击事件——FullCalendar的事件监听优先级更高,且这种方式并非官方推荐的禁用交互方案。 - 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
相关产品推荐
相关产品推荐

