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

如何使不同时长的外部Draggable事件与timeGridWeek内显示尺寸一致?

实现外部拖拽元素尺寸与FullCalendar timeGridWeek事件时长匹配

我之前也碰到过类似的需求,要让外部拖拽的事件在视觉上就和日历里对应时长的事件大小一致,核心思路就是把拖拽元素的尺寸和日历的时间格规则绑定起来,同时在拖拽过程中把预设的时长传递给日历事件。下面是具体的实现步骤和代码:

1. 给外部拖拽元素标记时长数据

首先在HTML里给每个可拖拽的事件元素加上data-duration属性,用来存储它对应的时长(单位:小时),方便后面JS直接读取:

<div id="external-events" class="external-events">
  <div class="fc-event" data-duration="1">1小时会议</div>
  <div class="fc-event" data-duration="2">2小时培训</div>
  <div class="fc-event" data-duration="4">半天工作坊</div>
</div>

2. 动态匹配拖拽元素的高度

FullCalendar的timeGrid视图有个内部参数minuteHeight,表示每分钟对应的像素高度。我们可以利用这个参数,在视图加载完成后,动态计算每个拖拽元素的高度,让它和日历里对应时长的事件高度完全一致:

document.addEventListener('DOMContentLoaded', function() {
  const calendarEl = document.getElementById('calendar');
  const externalEventsEl = document.getElementById('external-events');

  const calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'timeGridWeek',
    editable: true,
    droppable: true,
    // 视图加载完成后计算拖拽元素高度
    viewDidMount: function(info) {
      const minuteHeight = info.view.timeGrid.minuteHeight;
      const eventItems = externalEventsEl.querySelectorAll('.fc-event');
      
      eventItems.forEach(item => {
        const durationHours = parseInt(item.dataset.duration);
        // 计算核心高度:时长(小时)*60分钟 * 每分钟高度
        const contentHeight = durationHours * 60 * minuteHeight;
        // 加上元素的上下内边距(比如我这里设的是5px上下,所以加10px)
        item.style.height = `${contentHeight + 10}px`;
      });
    },
    // 处理拖拽到日历的事件
    eventReceive: function(info) {
      // 从拖拽元素读取时长,设置事件的结束时间
      const durationHours = parseInt(info.draggedEl.dataset.duration);
      const startTime = info.event.start;
      const endTime = new Date(startTime);
      endTime.setHours(startTime.getHours() + durationHours);
      
      // 更新事件的结束时间,这样日历里的事件时长就和拖拽元素一致了
      info.event.setEnd(endTime);
    }
  });

  calendar.render();

  // 初始化外部拖拽功能
  new FullCalendar.Draggable(externalEventsEl, {
    itemSelector: '.fc-event',
    eventData: function(eventEl) {
      // 返回事件的基础样式和标题
      return {
        title: eventEl.textContent.trim(),
        backgroundColor: window.getComputedStyle(eventEl).backgroundColor,
        borderColor: window.getComputedStyle(eventEl).backgroundColor
      };
    }
  });
});

3. 补充细节优化

  • 如果需要支持视图切换(比如从timeGridWeek切换到timeGridDay),可以监听viewDidChange事件,重新计算拖拽元素的高度,因为不同视图的minuteHeight可能不同。
  • 样式上可以给外部拖拽元素加上和日历事件一致的样式,让视觉统一:
.external-events {
  padding: 10px;
  background: #f5f5f5;
  border-radius: 4px;
}
.fc-event {
  padding: 5px 8px;
  margin: 8px 0;
  cursor: grab;
  border-radius: 3px;
  color: #fff;
  user-select: none;
}

这样一来,外部拖拽元素的高度会和日历里对应时长的事件完全匹配,用户拖拽前就能直观看到事件的时长,拖拽到日历后也不会出现尺寸和时长不符的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:30:53