FullCalendar 是事件调度日历的现实起点,因其真正支持拖拽、缩放、时区、资源分组及 timelineWeek 视图,且提供稳定 API(如 eventDrop、eventResize)、纯 JS 集成、ISO 8601 时间格式兼容、状态可视化钩子(eventClassNames)、资源列宽度控制(resourceAreaWidth)和导出适配方案(updateSize + overflow visible)。
为什么 FullCalendar 是事件调度器日历视图的现实起点
直接用原生 html/css 做可拖拽、可缩放、带时区和资源分组的日历视图,99% 的项目会卡在滚动同步、跨天事件渲染或键盘无障碍上。fullcalendar 不是“最轻量”的选择,但它是唯一把 eventdrop、eventresize、resources 和 timelineweek 视图真正跑通的开源方案。它不强制你用 react/vue,纯 js 版本(@fullcalendar/core + @fullcalendar/daygrid)也能直接挂 dom 上。
- 别碰
calendar.js或手写position: sticky表格 —— 时序错位、打印样式崩坏、移动端 touch 事件丢失是高频报错点 -
FullCalendar的slotMinTime/slotMaxTime控制可视时间范围,不是靠 CSS 隐藏;改这个比调height更稳 - 如果你用的是 Laravel 或 Django 后端,注意它的
events接口必须返回 ISO 8601 格式时间字符串(如"2024-06-15T09:30:00"),传 Unix 时间戳会静默失败
怎么让定时任务在日历里一眼看出「是否已执行」
状态可视化不是加个颜色就完事。用户真正需要的是:扫一眼就知道这任务是“待运行”“运行中”“失败重试中”还是“成功归档”。FullCalendar 的 eventClassNames 是最轻量的钩子,别用 eventRender 插 DOM —— 它在 v6+ 已废弃,且破坏 SSR 兼容性。
- 后端返回事件数据时,必须带一个明确的状态字段,比如
status: "failed",前端用它映射 CSS 类:eventClassNames: ({ event }) => [event.extendedProps.status] - 别把所有状态塞进一个
.event-failed里 —— 分开写.event-running、.event-succeeded,方便后期用 CSS 变量控制 opacity 或 border-style - 如果任务有重试次数,用
event.content(v6.2+)在标题后追加小 badge:content: () => `<span class="fc-event-badge">×3</span>`
,而不是拼接进title字符串 —— 否则导出会乱码
timelineWeek 视图下,横向拉伸资源列时宽度不一致怎么办
这是资源调度类场景(比如多台服务器、多个运维人员)最常踩的坑:resources 列表渲染后,第一列宽 200px,第二列只剩 120px,拖拽事件到第二列直接失焦。根本原因不是 CSS,而是 resourceAreaWidth 默认按文字长度算,没考虑图标或 badge 占位。
- 显式设
resourceAreaWidth: "240px",单位必须带px,写"240"或240会失效 - 资源名过长时,用
resourceLabelContent截断并加 tooltip:resourceLabelContent: ({ resource }) => ({ html: `<span title="${resource.title}">${resource.title.substring(0, 12)}…</span>` }) - 如果资源数动态变化(比如按环境筛选),别在初始化后手动调
calendar.render()—— 改用calendar.setOption("resources", newResources),否则横向滚动条会卡死
导出为 PNG 或 PDF 时事件位置偏移、文字被截断
浏览器原生打印或 html2canvas 截图时,FullCalendar 的绝对定位 + transform 缩放会让事件块“飘”出容器边界。这不是样式没写好,是它的渲染机制依赖运行时计算,而截图工具无法触发 resize 或 scroll 事件。
- 导出前先调用
calendar.updateSize(),再等 100ms 让布局稳定:await new Promise(r => setTimeout(r, 100))
- PDF 导出优先用服务端(如 Puppeteer),前端用
dom-to-image时,给日历容器加style="overflow: visible !important;",否则 overflow:hidden 会裁掉悬停弹窗和拖拽预览 - 字体 fallback 必须写全:
font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI",否则 Linux 服务器生成的 PDF 会默认用 Symbol 字体,中文全成方框
复杂点在于:事件状态、资源宽度、导出时机这三者互相影响。改一个参数往往要连带验证另外两个,尤其当用户同时打开 5 个标签页切来切去的时候。










