如何在FullCalendar中为入住/退房日期设置半宽事件?
嘿,这个需求完全可以实现,我给你分享两个实用的方案,亲测能解决你的问题:
方案一:拆分订单事件为三个分段
FullCalendar的日期规则是「包含起始、排除结束」,那我们可以把你的原订单拆成三个独立的事件,分别对应入住日半宽、中间时段全宽、退房日半宽:
- 入住事件:起始日期
2020-11-01,结束日期2020-11-02,给它加个自定义类名event-checkin - 中间时段事件:起始日期
2020-11-02,结束日期2020-11-07,类名event-full - 退房事件:起始日期
2020-11-07,结束日期2020-11-08,类名event-checkout
同时要确保这三个事件都关联同一个房间的resourceId(资源时间线视图必备)。事件数据示例大概是这样:
const bookingEvents = [ { title: '入住', start: '2020-11-01', end: '2020-11-02', resourceId: 'room-101', className: 'event-checkin' }, { title: '预订中', start: '2020-11-02', end: '2020-11-07', resourceId: 'room-101', className: 'event-full' }, { title: '退房', start: '2020-11-07', end: '2020-11-08', resourceId: 'room-101', className: 'event-checkout' } ];
然后用CSS控制宽度和位置:
/* 入住事件左半宽 */ .event-checkin { width: 50% !important; float: left; border-radius: 4px 0 0 4px; } /* 退房事件右半宽 */ .event-checkout { width: 50% !important; float: right; border-radius: 0 4px 4px 0; } /* 中间时段全宽 */ .event-full { width: 100% !important; }
这个方案的优点是简单直接,不需要复杂的自定义渲染,FullCalendar会自动处理事件的时间显示逻辑。
方案二:自定义事件渲染(eventContent)
如果不想拆分事件,也可以用FullCalendar的eventContent回调来自定义每个事件的HTML结构,根据事件的日期判断是入住、中间还是退房时段,然后渲染对应的半宽样式。
首先,你需要在初始化FullCalendar时配置eventContent:
document.addEventListener('DOMContentLoaded', function() { const calendarEl = document.getElementById('calendar'); const bookingStart = new Date('2020-11-01'); const bookingEnd = new Date('2020-11-07'); const calendar = new FullCalendar.Calendar(calendarEl, { // 你的视图配置(月视图、资源时间线月视图) views: { resourceTimelineMonth: { type: 'resourceTimelineMonth' } }, resources: [/* 你的房间资源数据 */], events: [{ title: '预订', start: '2020-11-01', end: '2020-11-07', resourceId: 'room-101' }], eventContent: function(info) { let eventClass = 'event-full'; // 判断当前事件片段是否是入住日 if (info.event.start.toDateString() === bookingStart.toDateString()) { eventClass = 'event-checkin'; } // 判断当前事件片段是否是退房日 if (info.event.start.toDateString() === bookingEnd.toDateString()) { eventClass = 'event-checkout'; } return { html: `<div class="fc-event-title-container ${eventClass}"> <div class="fc-event-title">${info.event.title}</div> </div>` }; } }); calendar.render(); });
然后同样用方案一的CSS来控制宽度即可。这个方案适合需要保留单个事件对象的场景,比如后续要对整个订单做操作(比如取消、修改),不需要处理多个事件的关联。
额外注意事项
- 资源时间线视图中,一定要确保事件的
resourceId和房间资源的id匹配,不然事件会显示错误 - CSS中的
!important可能需要根据FullCalendar的版本调整,如果默认样式优先级更高,就需要用更具体的选择器(比如.fc-event.event-checkin) - 如果是批量处理订单,建议写一个工具函数,自动把单个订单拆分成三个事件,避免手动重复劳动
内容的提问来源于stack exchange,提问作者Aaqib
相关产品推荐
相关产品推荐

