Fullcalendar开发:为事件内日期网格设置开闭背景标识
实现FullCalendar月视图按星期几着色事件范围内的日期
嘿,这个需求我刚好做过类似的,给你分享两种可行的实现方式,还有你问的resources/constraints是否适用的问题~
核心需求拆解
你需要在月视图中,针对每个事件的open_xxx字段,给事件时间范围内对应星期几的日期网格设置红绿背景,无事件的日期保持空白。
方案一:利用dayCellDidMount钩子操作DOM(适合v5+版本)
这是直接操作单元格元素的方式,适合快速实现:
代码示例
document.addEventListener('DOMContentLoaded', function() { const calendarEl = document.getElementById('calendar'); const calendar = new FullCalendar.Calendar(calendarEl, { initialView: 'dayGridMonth', // 你的事件数据 events: [ { id: "sdsddsd", start: "2018-05-13T00:00:00", end: "2018-05-26T00:00:00", open_monday: true, open_tuesday: false, open_wednesday: true, open_thursday: false, open_friday: true, open_saturday: false, open_sunday: false } ], // 每个日期单元格渲染完成时触发 dayCellDidMount: function(info) { // 先清除之前的背景色,避免单元格复用导致的样式残留 info.el.style.backgroundColor = ''; const currentDate = info.date; // 获取当前视图的所有事件 const events = calendar.getEvents(); events.forEach(event => { const eventStart = event.start; const eventEnd = event.end; // 检查当前日期是否在事件的时间范围内(注意end是排他的) if (currentDate >= eventStart && currentDate < eventEnd) { const dayOfWeek = currentDate.getDay(); // 0=周日,1=周一...6=周六 let color = ''; // 根据星期几匹配对应的open_xxx字段 switch(dayOfWeek) { case 1: color = event.extendedProps.open_monday ? 'green' : ''; break; case 2: color = !event.extendedProps.open_tuesday ? 'red' : ''; break; case 3: color = event.extendedProps.open_wednesday ? 'green' : ''; break; case 4: color = !event.extendedProps.open_thursday ? 'red' : ''; break; case 5: color = event.extendedProps.open_friday ? 'green' : ''; break; case 6: color = !event.extendedProps.open_saturday ? 'red' : ''; break; case 0: color = !event.extendedProps.open_sunday ? 'red' : ''; break; } if (color) { // 如果有多个事件重叠,这里会覆盖之前的颜色,你可以调整为叠加透明度等逻辑 info.el.style.backgroundColor = color; } } }); }, // 视图切换或事件更新时,重新渲染确保样式正确 viewDidMount: () => calendar.render(), eventDidMount: () => calendar.render() }); calendar.render(); });
关键说明
extendedProps:FullCalendar会把自定义字段(比如你的open_monday)放在事件对象的extendedProps属性下,所以要通过这个路径访问。- 单元格复用处理:一定要先清除背景色,否则切换视图时旧样式会残留。
- 多事件重叠:如果同一个日期被多个事件覆盖,你可以根据需求调整颜色优先级,比如叠加
rgba(0,255,0,0.5)这样的半透明色。
方案二:生成背景事件(更优雅的原生实现)
FullCalendar支持背景事件(background events),可以自动填充日期单元格,不需要手动操作DOM,这是更推荐的方式:
代码示例
document.addEventListener('DOMContentLoaded', function() { const calendarEl = document.getElementById('calendar'); // 原始事件数据 const originalEvents = [ { id: "sdsddsd", start: "2018-05-13T00:00:00", end: "2018-05-26T00:00:00", open_monday: true, open_tuesday: false, open_wednesday: true, open_thursday: false, open_friday: true, open_saturday: false, open_sunday: false } ]; // 生成背景事件的工具函数 function createBackgroundEvents(events) { const backgroundEvents = []; events.forEach(event => { const startDate = new Date(event.start); const endDate = new Date(event.end); // 遍历事件范围内的每一天 for (let date = new Date(startDate); date < endDate; date.setDate(date.getDate() + 1)) { const dayOfWeek = date.getDay(); let bgColor = ''; switch(dayOfWeek) { case 1: bgColor = event.open_monday ? 'green' : ''; break; case 2: bgColor = !event.open_tuesday ? 'red' : ''; break; case 3: bgColor = event.open_wednesday ? 'green' : ''; break; case 4: bgColor = !event.open_thursday ? 'red' : ''; break; case 5: bgColor = event.open_friday ? 'green' : ''; break; case 6: bgColor = !event.open_saturday ? 'red' : ''; break; case 0: bgColor = !event.open_sunday ? 'red' : ''; break; } if (bgColor) { backgroundEvents.push({ start: new Date(date), end: new Date(date.setDate(date.getDate() + 1)), display: 'background', // 标记为背景事件 backgroundColor: bgColor, borderColor: 'transparent' // 去掉背景事件的边框,更美观 }); } } }); return backgroundEvents; } // 合并原始事件和背景事件 const allEvents = [...originalEvents, ...createBackgroundEvents(originalEvents)]; const calendar = new FullCalendar.Calendar(calendarEl, { initialView: 'dayGridMonth', events: allEvents }); calendar.render(); });
优点
- 完全利用FullCalendar原生机制,避免DOM操作带来的潜在问题(比如视图切换时的样式混乱)。
- 维护更简单:如果事件更新,只需要重新生成背景事件即可。
- 支持事件的所有原生特性(比如过滤、搜索),背景事件会自动跟随。
关于resources和constraints的适用性
这两个特性其实和你的需求不匹配:
- resources:主要用于资源日历场景(比如会议室、人员排班),每个资源对应一列,和你按星期几着色日期的需求无关。
- constraints:用于限制事件的拖动、调整大小范围,或者限制事件只能在特定时间段,和背景着色没有关系。
所以这两个方案都不是你的需求的最优解,推荐用上面的第二种背景事件方案。
内容的提问来源于stack exchange,提问作者Aviz
相关产品推荐
相关产品推荐

