FullCalendar时间线模式下如何实现相邻资源事件合并?
FullCalendar时间线模式多资源事件合并实现方案
1. 调整事件数据结构
给事件添加resourceIds数组,明确关联的所有资源ID:
events: [ { title: "多人聚餐", start: "2024-05-20T12:00:00", end: "2024-05-20T18:00:00", resourceIds: ["100", "101"] // 关联相邻桌台100、101 }, { title: "团队会议", start: "2024-05-20T10:00:00", end: "2024-05-20T14:00:00", resourceIds: ["100", "103"] // 关联不相邻桌台100、103 } ]
2. 自定义事件渲染(核心实现)
利用eventContent和eventDidMount回调,判断资源连续性并渲染对应样式:
document.addEventListener('DOMContentLoaded', function() { const calendarEl = document.getElementById('calendar'); // 提前存储资源列表,用于判断连续性 const resources = [ { id: "100", title: "桌台100" }, { id: "101", title: "桌台101" }, { id: "102", title: "桌台102" }, { id: "103", title: "桌台103" } ]; const calendar = new FullCalendar.Calendar(calendarEl, { schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source', initialView: 'resourceTimelineDay', resources: resources, events: [/* 你的事件数据 */], eventContent: function(info) { const eventResources = info.event.getResources(); const currentResource = info.resource; // 仅在关联的第一个资源上渲染,其余资源跳过 if (eventResources[0].id !== currentResource.id) { return { html: '' }; } // 判断资源是否连续 let isContiguous = true; for (let i = 1; i < eventResources.length; i++) { const prevIndex = resources.findIndex(r => r.id === eventResources[i-1].id); const currIndex = resources.findIndex(r => r.id === eventResources[i].id); if (currIndex !== prevIndex + 1) { isContiguous = false; break; } } if (isContiguous) { return { html: `<div class="fc-event-merged">${info.event.title}</div>` }; } else { // 资源不相邻,正常渲染单个事件 return { html: `<div>${info.event.title}</div>` }; } }, eventDidMount: function(info) { const eventResources = info.event.getResources(); if (eventResources.length > 1 && eventResources[0].id === info.resource.id) { const rowHeight = calendar.view.resourceGrid.getRowHeight(); // 让合并事件覆盖对应数量的资源行 info.el.style.height = `${rowHeight * eventResources.length}px`; info.el.style.top = '0'; info.el.style.zIndex = 10; } } }); calendar.render(); });
3. 补充样式优化
添加CSS确保合并事件的视觉效果:
.fc-event-merged { background-color: #378006; border: none; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 600; }
关键逻辑说明
- 资源连续时:仅在第一个关联资源位置渲染一个覆盖所有对应资源行的合并区块,其余关联资源位置不渲染事件。
- 资源不连续时:每个关联资源独立显示该事件,保持原有逻辑。
内容的提问来源于stack exchange,提问作者Gandalf Corvotempesta
相关产品推荐
相关产品推荐

