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

如何在FullCalendar主事件首尾添加固定时长的准备与收尾时段

绑定主事件准备/收尾时段的FullCalendar v5.10.1实现方案

核心思路

放弃创建独立的准备/收尾事件,转而通过扩展主事件属性+自定义渲染+内置事件钩子实现需求:把准备/收尾时段作为主事件的一部分计算时间范围,用渲染区分样式,靠FullCalendar原生机制处理同步和重叠,彻底解决性能和关联失效问题。

1. 给主事件添加自定义属性

在主事件数据中加入准备、收尾的时长参数,用于后续计算完整时间范围:

// 示例主事件数据
{
  id: 'conf-room-1',
  title: '会议室A租赁',
  start: '2024-05-20T10:00:00',
  end: '2024-05-20T12:00:00',
  prepDuration: 30, // 准备时长(分钟)
  wrapupDuration: 30, // 收尾时长(分钟)
  editable: true, // 主事件可编辑
  isMainEvent: true // 标记为主事件
}

2. 实现完整范围的重叠阻止

利用eventOverlap回调,计算主事件包含准备/收尾的完整时间范围,阻止其他事件与该范围重叠:

eventOverlap: function(stillEvent, movingEvent) {
  if (!movingEvent.extendedProps.isMainEvent) return true;
  
  // 计算主事件的完整占用时间(准备+主时段+收尾)
  const prepStart = moment(movingEvent.start).subtract(movingEvent.extendedProps.prepDuration, 'minutes').toDate();
  const wrapupEnd = moment(movingEvent.end).add(movingEvent.extendedProps.wrapupDuration, 'minutes').toDate();
  
  // 判断其他事件是否与完整范围重叠
  return !(
    moment(stillEvent.start).isBefore(wrapupEnd) &&
    moment(stillEvent.end).isAfter(prepStart)
  );
}

3. 同步准备/收尾与主事件的移动、调整

监听主事件的拖拽和调整事件,触发重新渲染即可自动同步准备/收尾时段,无需重建事件:

document.addEventListener('DOMContentLoaded', function() {
  const calendar = new FullCalendar.Calendar(document.getElementById('calendar'), {
    // 其他基础配置
    eventDrop: function(info) {
      if (info.event.extendedProps.isMainEvent) {
        calendar.refetchEvents(); // 触发重渲染,自动同步准备/收尾位置
      }
    },
    eventResize: function(info) {
      if (info.event.extendedProps.isMainEvent) {
        calendar.refetchEvents(); // 调整时长后,收尾时段自动延后
      }
    }
  });
  calendar.render();
});

4. 自定义渲染区分主时段与准备/收尾

用eventContent回调生成事件的HTML结构,给准备/收尾部分添加不可点击样式,视觉上区分不同时段:

eventContent: function(info) {
  if (!info.event.extendedProps.isMainEvent) {
    return { html: info.event.title };
  }
  
  const { prepDuration, wrapupDuration } = info.event.extendedProps;
  const totalMinutes = (moment(info.event.end).diff(info.event.start, 'minutes') + prepDuration + wrapupDuration);
  // 计算各时段的宽度比例
  const prepWidth = (prepDuration / totalMinutes) * 100;
  const mainWidth = (moment(info.event.end).diff(info.event.start, 'minutes') / totalMinutes) * 100;
  const wrapupWidth = (wrapupDuration / totalMinutes) * 100;
  
  return {
    html: `
      <div class="event-box">
        <div class="event-prep" style="width: ${prepWidth}%; pointer-events: none;">准备</div>
        <div class="event-main" style="width: ${mainWidth}%;">${info.event.title}</div>
        <div class="event-wrapup" style="width: ${wrapupWidth}%; pointer-events: none;">收尾</div>
      </div>
    `
  };
}

5. 月视图隐藏准备/收尾时段

通过eventClassNames给主事件添加视图专属类,配合CSS在月视图下隐藏准备/收尾:

eventClassNames: function(arg) {
  if (arg.event.extendedProps.isMainEvent && arg.view.type === 'dayGridMonth') {
    return ['hide-prep-wrapup'];
  }
  return [];
}

对应的CSS:

.hide-prep-wrapup .event-prep,
.hide-prep-wrapup .event-wrapup {
  display: none;
}
.hide-prep-wrapup .event-main {
  width: 100% !important;
}

方案优势

  • 无需创建独立事件,避免groupId关联失效和删除重建的性能损耗
  • 依托FullCalendar原生机制处理重叠和同步,逻辑更稳定
  • 自定义渲染直接在主事件内区分时段,无独立事件的同步偏差问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:06:25