FullCalendar eventDrop跨午夜判断拖放日期及agendaWeek视图日程问题
Hey there, let's break down these two FullCalendar challenges you're facing—they're super common once you start working with cross-day events, so I've got some practical fixes for you!
When dealing with eventDrop for events that span midnight, the simplest and most reliable way to find the target day is to look at the new start property of the event after the drag completes. FullCalendar automatically aligns the event's start time to the calendar cell/area you dragged it to, regardless of whether the event crosses midnight.
Here's how to implement it:
- For FullCalendar v5+ (uses native
Dateobjects):eventDrop: function(info) { // Extract the date part from the new start time const targetDate = info.event.start.toISOString().split('T')[0]; console.log('Event dropped onto:', targetDate); } - For older versions (uses Moment.js):
eventDrop: function(info) { const targetDate = info.event.start.format('YYYY-MM-DD'); console.log('Event dropped onto:', targetDate); }
If you need to confirm the exact calendar cell the user dragged to (instead of just the event's start date), you could calculate it using the mouse position from info.jsEvent, but in most cases, the event's start date is all you need—it directly reflects the day the user intended to drop the event onto.
That bug where dragging an event to a day's start position results in the start time landing on the previous day is annoying, but easy to fix with a little post-drag validation in the eventDrop callback. Here's why it happens: FullCalendar's drag detection might snap the event to a nearby time slot (like 23:59 of the previous day) instead of the exact 00:00 of the target day, especially if your agenda view has small time increments.
Here's a step-by-step fix that works alongside your existing end-time truncation code:
eventDrop: function(info) { const event = info.event; const durationMs = event.end.getTime() - event.start.getTime(); // Save original event duration // Fix 1: Correct start time if it's just before midnight of the target day const startHours = event.start.getHours(); const startMinutes = event.start.getMinutes(); // Check if start is in the last 10 minutes of the previous day (adjust threshold as needed) if (startHours === 23 && startMinutes >= 50) { // Shift start to midnight of the intended target day const correctedStart = new Date( event.start.getFullYear(), event.start.getMonth(), event.start.getDate() + 1, 0, 0, 0 ); // Adjust end time to keep the original duration const correctedEnd = new Date(correctedStart.getTime() + durationMs); event.setStart(correctedStart); event.setEnd(correctedEnd); info.view.calendar.updateEvent(event); } // Fix 2: Your existing code to truncate end time to midnight of the start date const startDateMidnight = new Date( event.start.getFullYear(), event.start.getMonth(), event.start.getDate() + 1, 0, 0, 0 ); if (event.end > startDateMidnight) { event.setEnd(startDateMidnight); info.view.calendar.updateEvent(event); } }
A few notes to tweak this for your setup:
- Adjust the time threshold (10 minutes in the example) based on your agenda view's time slot size—if you use 30-minute slots, you might want to check for 23:30 or later.
- If you're using Moment.js instead of native Dates, swap out the
Dateconstructor calls with Moment methods likemoment().startOf('day')andadd(duration, 'minutes').
内容的提问来源于stack exchange,提问作者karlmnz

