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

FullCalendar月视图头部自定义:显示前后月份名称

解决FullCalendar头部显示前后月份+当前月份的需求

要实现日历头部显示「前一个月 + 当前月 + 后一个月」的效果,核心思路是自定义日历头部的标题区域,利用FullCalendar的日期钩子函数动态计算并渲染三个月份的名称。以下是具体实现方案:

关键修改步骤

  • 移除默认的title配置,改用自定义元素承载三个月份名称
  • 通过datesSet钩子监听视图切换,实时计算前后月份并更新头部显示
  • 利用FullCalendar内置的日期格式化工具生成对应语言的月份名称

修改后的完整代码

function drawCalendar() {
    const calendarEl = document.getElementById('calendar');
    
    const calendar = new FullCalendar.Calendar(calendarEl, {
        locale: 'ru',
        initialView: 'dayGridMonth',
        fixedWeekCount: false,
        firstDay: 1,
        displayEventTime: false,
        height: 700,
        
        dayMaxEventRows: true, // for all non-TimeGrid views
        views: {
            timeGrid: {
                dayMaxEventRows: 6 // adjust to 6 only for timeGridWeek/timeGridDay
            }
        },
                
        headerToolbar: {
            left: 'prev',
            center: 'customTitle', // 替换默认title为自定义标题区域
            right: 'next'
        },
        // 注册自定义按钮作为标题容器
        customButtons: {
            customTitle: {
                text: '', // 初始为空,后续动态填充
                click: function() {} // 空点击事件,避免触发默认行为
            }
        },
       
        views: {
            dayGridMonth: {
                dayHeaderFormat: {
                    weekday: 'long',
                }
            }
        },

        events: eventsArray,

        eventClick: function(info) {
            showEvent(info);
        },

        eventDidMount: function (info) {
            if (info.event.backgroundColor) {
                info.el.style.background = info.event.backgroundColor;
            }
        },
        // 视图日期切换时触发,更新标题
        datesSet: function(info) {
            const currentMonth = info.view.currentStart;
            // 计算前一个月
            const prevMonth = new Date(currentMonth);
            prevMonth.setMonth(prevMonth.getMonth() - 1);
            // 计算后一个月
            const nextMonth = new Date(currentMonth);
            nextMonth.setMonth(nextMonth.getMonth() + 1);

            // 格式化生成俄语完整月份名称
            const prevMonthName = calendar.formatDate(prevMonth, { month: 'long' });
            const currentMonthName = calendar.formatDate(currentMonth, { month: 'long' });
            const nextMonthName = calendar.formatDate(nextMonth, { month: 'long' });

            // 更新自定义标题文本
            document.querySelector('.fc-customTitle-button').textContent = `${prevMonthName} ${currentMonthName} ${nextMonthName}`;
        }
    });
    
    calendar.render();
    // 初始化时手动触发一次,确保初始显示正确
    calendar.datesSet();
};

drawCalendar();

let eventBlock = document.getElementById("event__modal");

function showEvent(info) {
    document.getElementById("event__overlay").classList.toggle("slidedIntoView");
    eventBlock.innerHTML = "";

    const categoryColor = info.event.extendedProps.category === 'Презентация' ? '#349EFF' : '#FFAE34';
    eventBlock.innerHTML += `
        <div class="event__modal">
            <div class="event__modal__top">
                <div class="event__modal__category" style="background-color: ${categoryColor}">${info.event.extendedProps.category}</div>
                <img src="images/close-modal-icon.png" onclick="closeEvent()" alt="Иконка закрытия" class="close__icon">
            </div>
            <div class="event__modal__title">${info.event.title}</div>
            <div class="event__modal__spikers">${info.event.extendedProps.spikers}</div>
            <div class="event__modal__description">${info.event.extendedProps.description}</div>
            <div class="event__modal_bottom">
                <div class="event__modal__time">Состоится ${info.event.start.toLocaleDateString()}</div>
                <div class="event__modal__reminder">
                    <button class="event__modal__reminder__button">Напомнить</button>
                    <img src="images/reminder-icon.png" alt="Иконка напоминания" class="reminder__icon">
                </div>
            </div>
        </div>
    `;
}

function closeEvent(event) {
    document.getElementById("event__overlay").classList.remove("slidedIntoView");
}

代码说明

  • 自定义标题容器:通过customButtons创建customTitle按钮,替换默认的title区域,避免FullCalendar默认的单月份渲染逻辑
  • 动态日期计算:在datesSet钩子中,基于当前视图的起始日期,通过setMonth方法快速计算前后月份
  • 本地化格式化:利用calendar.formatDate结合locale: 'ru'配置,自动生成俄语的完整月份名称
  • 初始化兼容:日历渲染后手动调用datesSet(),确保首次加载时就能显示正确的三个月份
  • 额外优化:简化模态框的颜色判断逻辑,避免重复代码;日期显示改用toLocaleDateString()优化格式可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:12:34