日历【FullCalendar+Lunar+RRule+Popper】
先看官方文档,不懂的再chatgpt,最后谷歌百度搜问题
FullCalendar
- 视图
- 单元格渲染
- 单元格大小适配
确保计算和数据加载完毕,延迟100ms渲染。
1 | datesSet: |
Lunar
- 法定节假日
- 节气
- 农历日期
- 宜忌
- 生日
RRule
命名空间
1
2
3const rruleOccurrences = new RRule(rruleEvent.rrule).all();
//无法识别 RRule,提示未定义,我们引入了rrule库就要引入命名空间 rrule
var RRule = rrule.RRule;格式与FullCalendar插件语法不同:
- FullCalendar语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14var calendar2 = new FullCalendar.Calendar(calendarEl, {
events: [
{
title: 'my recurring event',
rrule: {
freq: 'weekly',
interval: 1,
byweekday: ['mo', 'fr'],
dtstart: '2024-02-01T10:30:00', // will also accept '20120201T103000'
until: '2025-06-01' // will also accept '20120201'
}
}
]
}); - RRule 语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23var RRule = rrule.RRule;
var rruleEvent =
{
title: 'rrule event',
rrule: {
freq: RRule.WEEKLY,
interval: 5,
byweekday: [RRule.MO, RRule.FR],
dtstart: new Date(2024, 2, 1, 10, 30),
until: new Date(2025, 12, 31)
},
duration: '02:00',
};
// 使用 rrule.js 解析 RRule
console.log(typeof RRule); // 应该输出 "function"
const rruleOccurrences = new RRule(rruleEvent.rrule).all(); // 获取所有日期实例
// 转换为 FullCalendar 可用事件格式
const rruleEvents = rruleOccurrences.map(date => ({
title: rruleEvent.title,
start: date,
}));
- FullCalendar语法
单个对象声明
在还没有做好重复事件配置处理时,保持按照单个声明,这个和其他event配置不同。因为一个重复事件肯能涉及好多时间段,相当于多个事件的集合。events 属性和 evens 函数不可兼得
evens 函数:更灵活,配置变量,但是重复事件要自己转换
events 属性:死板,但是支持重复事件,根据FullCalendar语法来1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
events: [...birthdayEvents, ...myEvents, ...InternationalFestivals, ...rruleEvents],
or
events: function (info, successCallback, failureCallback) {
// 获取当前视图的起始日期
const viewStart = new Date(info.start);
const curMonthIndex = (viewStart.getDate() !== 1) ? viewStart.getMonth() + 1 : viewStart.getMonth();//月份下标 0-11 12是下一年1月
currentYear = (viewStart.getMonth() === 11 && curMonthIndex === 12) ? viewStart.getFullYear() + 1 : viewStart.getFullYear();
var curMonth = curMonthIndex == 12 ? 1 : curMonthIndex + 1;
const solar = Solar.fromYmd(currentYear, curMonth, 1); // 构造阳历日期
const lunar = solar.getLunar(); // 转为农历日期
var curYearLunar = lunar.getYear();
console.log('当前显示的主月份年份是:', currentYear, ' ', curMonth, ' ', lunar.toString(), ' ', solar.toString());
defineBirthday(curYearLunar);
AddAnniversaryDate();
defineMyEvent();
defineInternationalFestivals();
// 合并所有事件数组
const allEvents = [...birthdayEvents, ...myEvents, ...InternationalFestivals, ...rruleEvents];
// 过滤出在当前视图范围内的事件
const filteredEvents = allEvents.filter(event => {
const eventStart = new Date(event.start).getTime();
const eventEnd = event.end ? new Date(event.end).getTime() : eventStart;
// 判断事件是否与视图范围有重叠
return eventEnd >= new Date(info.start).getTime() && eventStart <= new Date(info.end).getTime();
});
// 返回过滤后的事件
successCallback(filteredEvents);
},
Popper
鼠标进入时事件详情弹窗
1 | eventDidMount: function (info) { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LiuCheng's Blog!
评论