如何在FullCalendar v3中实现EaseMyTrip移动端日历的节假日展示
FullCalendar v3 实现节假日标注效果
需求说明
- 在月视图顶部标题旁显示当月节假日总数
- 有节假日的日期单元格上展示带数字的圆形徽章(1、2、3...)
- 月视图底部添加节假日数字对应的名称说明栏
完整实现代码
HTML 代码
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css" rel="stylesheet"/> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.js"></script> <div id="calendar"></div>
CSS 代码
.circle_dot { font-size: 9px; width: 12px; height: 12px; background: #FFE3A2; border-radius: 50%; color: #000; align-items: center; justify-content: center; font-weight: 500; position: absolute; top: 0px; opacity: 1; display: flex; /* 确保数字居中显示 */ } /* 底部节假日说明栏样式 */ .holiday-legend { padding: 10px; text-align: center; background: #f8f8f8; margin-top: 10px; border-radius: 4px; } .holiday-legend-item { display: inline-block; margin: 0 15px; font-size: 14px; } .holiday-legend-badge { display: inline-block; width: 12px; height: 12px; border-radius: 50%; background: #FFE3A2; margin-right: 5px; vertical-align: middle; text-align: center; font-size: 9px; line-height: 12px; color: #000; }
JavaScript 代码
$(document).ready(function () { // 维护节假日数据:日期 => [{数字标识: 节假日名称}, ...] const holidayData = { "2023-06-11": [{num: 1, name: "端午节"}], "2023-06-12": [{num: 2, name: "父亲节"}], "2023-06-20": [{num: 3, name: "夏至"}] }; // 计算指定月份的节假日总数 function getMonthHolidayCount(year, month) { let count = 0; Object.keys(holidayData).forEach(dateStr => { const date = moment(dateStr); if (date.year() === year && date.month() === month) { count += holidayData[dateStr].length; } }); return count; } // 生成节假日徽章事件数组 function generateHolidayEvents() { let events = []; Object.keys(holidayData).forEach(dateStr => { holidayData[dateStr].forEach(item => { events.push({ title: item.num.toString(), start: dateStr, className: 'circle_dot', allDay: true, holidayName: item.name // 自定义字段存储节假日名称 }); }); }); return events; } // 生成底部节假日说明栏HTML function generateLegendHtml() { let html = '<div class="holiday-legend">'; let legendItems = []; Object.keys(holidayData).forEach(dateStr => { holidayData[dateStr].forEach(item => { legendItems.push(`<span class="holiday-legend-item"><span class="holiday-legend-badge">${item.num}</span>${item.name}</span>`); }); }); // 去重处理(避免重复展示相同数字的说明) const uniqueItems = [...new Set(legendItems)]; html += uniqueItems.join(''); html += '</div>'; return html; } $('#calendar').fullCalendar({ header: { left: 'today', center: 'title', right: 'prev,next' }, views: { month: { titleFormat: function(date) { const year = date.year(); const month = date.month(); const count = getMonthHolidayCount(year, month); return `${date.format('MMM YYYY')} (节假日${count}个)`; } } }, buttonText: { today: '今天', prev: '<', next: '>' }, defaultDate: '2023-06-09', fixedWeekCount: false, showNonCurrentDates: false, navLinks: false, editable: false, eventLimit: false, selectable: true, selectHelper: true, dayClick: function(date) { alert(date.format('YYYY-MM-DD')); }, eventClick: function(calEvent) { if (calEvent.holidayName) { alert(calEvent.holidayName); } }, eventSources: [ // 原有业务状态事件 { events: [ {title: 'FULL', start: '2023-06-11', color: '#e66d1d'}, {title: 'AVAILABLE', start: '2023-06-12', color: '#257e4a', textColor: '#ffffff'}, {title: 'FULL', start: '2023-06-23', color: '#e66d1d'}, {title: 'AVAILABLE', start: '2023-06-28'} ] }, // 节假日徽章事件 { events: generateHolidayEvents() } ], // 月视图渲染完成后添加底部说明栏 viewRender: function(view, element) { if (view.name === 'month') { $('.holiday-legend').remove(); $(element).after(generateLegendHtml()); } } }); });
实现逻辑说明
- 顶部节假日总数:通过月视图的
titleFormat函数,实时计算当前视图月份的节假日数量并追加到标题中。 - 日期数字徽章:将节假日数据转换为FullCalendar事件,使用自定义
circle_dot类实现圆形数字徽章样式,同时通过自定义字段holidayName存储节假日名称。 - 底部说明栏:在
viewRender钩子中,当月视图渲染完成后生成并插入说明栏,确保数字与节假日名称一一对应,样式与徽章保持统一。
内容的提问来源于stack exchange,提问作者Nikhil
相关产品推荐
相关产品推荐

