如何基于JSON数据为Vanilla Calendar日期元素追加事件标识div?
如何在Vanilla Calendar的对应日期上追加事件标识div?
需求与数据结构
我需要在Vanilla Calendar的对应日期元素上追加div,标识该日期存在事件。事件信息存储在JSON文件中,结构如下:
{ "events": [ { "2023-08": [ { "2023-08-29": [ { "eventID1": [ { "title": "Event Title", "category": "Category" } ] }, { "eventID2": [ { "title": "Event Title", "category": "Category" } ] } ] }, { "2023-08-30": [ { "eventID1": [ { "title": "Event Title", "category": "Category" } ] }, { "eventID2": [ { "title": "Event Title", "category": "Category" } ] } ] } ] }, { "2023-09": [ { "2023-09-29": [ { "eventID1": [ { "title": "Event Title", "category": "Category" } ] }, { "eventID2": [ { "title": "Event Title", "category": "Category" } ] } ] }, { "2023-09-30": [ { "eventID1": [ { "title": "Event Title", "category": "Category" } ] }, { "eventID2": [ { "title": "Event Title", "category": "Category" } ] } ] } ] } ] }
日历DOM结构说明
日历的日期按钮带有data-calendar-day属性,值为完整日期格式,示例如下:
<button class="vanilla-calendar-day__btn vanilla-calendar-day__btn_today" type="button" data-calendar-day="2023-08-29">29</button>
月份容器则带有data-calendar-selected-month属性(值为0-11,对应1-12月)。
我的现有尝试
目前我尝试了以下代码,但不确定如何处理大量数据的循环逻辑:
eventData = data.events; drawEvent(data) function drawEvent(data) { for (events in data) { var eventEntries = data[*date?*] for (var i = 0; i < eventEntries.length; i++) { //append the div here? } } }
正确的循环实现方案
你的JSON结构嵌套层级较多,需要逐层遍历解析,具体步骤如下:
- 遍历年月对象数组:
data.events是一个数组,每个元素是一个仅包含一个年月键(如2023-08)的对象 - 提取年月与日期数组:对每个年月对象,取出唯一的年月键,以及对应的日期数组
- 遍历日期对象数组:每个日期数组里的元素是仅包含一个日期键(如
2023-08-29)的对象 - 提取日期与事件列表:对每个日期对象,取出唯一的日期键,以及对应的事件ID数组
- 匹配日历元素并追加标识:根据日期键找到对应的日历按钮,创建div追加到按钮内部
完整实现代码:
// 假设data是已加载的JSON数据 const eventData = data.events; drawEvents(eventData); function drawEvents(eventsArray) { // 1. 遍历每个年月对象 eventsArray.forEach(monthObj => { // 取出年月键(每个对象只有一个键) const yearMonth = Object.keys(monthObj)[0]; // 获取该年月下的所有日期对象数组 const dateObjects = monthObj[yearMonth]; // 2. 遍历每个日期对象 dateObjects.forEach(dateObj => { // 取出日期键(每个对象只有一个键) const fullDate = Object.keys(dateObj)[0]; // 获取该日期下的所有事件(这里可以根据需要使用事件数据) const events = dateObj[fullDate]; // 3. 根据日期查找对应的日历按钮 const dayButton = document.querySelector(`[data-calendar-day="${fullDate}"]`); if (dayButton) { // 4. 创建并追加事件标识div const eventMarker = document.createElement('div'); // 可以给div加类名方便样式控制 eventMarker.classList.add('event-marker'); // 也可以根据事件数量或类别设置不同样式 eventMarker.style.backgroundColor = '#ff4444'; eventMarker.style.width = '8px'; eventMarker.style.height = '8px'; eventMarker.style.borderRadius = '50%'; eventMarker.style.marginTop = '4px'; dayButton.appendChild(eventMarker); } }); }); }
关键细节说明
- 使用
Object.keys()获取对象的唯一键:因为你的JSON结构中,每个嵌套对象都只有一个键(年月或日期),所以取数组第一个元素即可拿到对应的年月/日期值 - 使用
forEach遍历数组:相比for循环更简洁易读,适合处理数组型数据 - 元素查找时添加判断:避免找不到元素时报错
- 可扩展性:可以根据事件的
category给标识div设置不同的样式,或者根据事件数量添加多个标识
内容的提问来源于stack exchange,提问作者weareonline
相关产品推荐
相关产品推荐

