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

JavaScript无法将JSON数据渲染到时间日程表问题求助

问题解决建议

1. 先确认基础HTML结构

确保页面有正确的表格容器,避免因DOM节点缺失导致渲染失败:

<table id="scheduleTable" border="1">
  <thead>
    <tr>
      <th>时间</th>
      <th>周一</th>
      <th>周二</th>
      <th>周三</th>
      <th>周四</th>
      <th>周五</th>
      <th>周六</th>
      <th>周日</th>
    </tr>
  </thead>
  <tbody id="scheduleBody"></tbody>
</table>

JS中先校验DOM节点是否存在:

const tbody = document.getElementById('scheduleBody');
if (!tbody) {
  console.error('找不到表格tbody元素');
  return;
}

2. 生成标准时间区间列表

将07:00 AM至07:00 PM的30分钟间隔时间,转换为24小时制时间键(用于匹配计算)和12小时制显示文本:

function generateTimeSlots() {
  const slots = [];
  let currentTime = new Date();
  currentTime.setHours(7, 0, 0, 0);
  const endTime = new Date();
  endTime.setHours(19, 0, 0, 0);

  while (currentTime <= endTime) {
    const displayTime = currentTime.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
    const timeKey = currentTime.toLocaleTimeString('en-GB', { hour24: true, hour: '2-digit', minute: '2-digit' });
    slots.push({ display: displayTime, key: timeKey });
    currentTime.setMinutes(currentTime.getMinutes() + 30);
  }
  return slots;
}

const timeSlots = generateTimeSlots();

3. 预处理日程数据,计算合并行数

按星期分组日程,同时计算每个日程需要合并的行数(每30分钟对应一行,时长/30即为rowspan):

// 替换为你实际获取的JSON数据
const scheduleData = [
  { dayOfWeek: "周一", startTime: "07:00", endTime: "10:00", title: "项目例会" },
  { dayOfWeek: "周三", startTime: "09:30", endTime: "11:00", title: "技术分享" }
];

const groupedData = {};
scheduleData.forEach(item => {
  if (!groupedData[item.dayOfWeek]) groupedData[item.dayOfWeek] = [];
  
  const start = new Date(`2020-01-01T${item.startTime}`);
  const end = new Date(`2020-01-01T${item.endTime}`);
  const durationMinutes = (end - start) / (1000 * 60);
  const rowspan = durationMinutes / 30;
  
  groupedData[item.dayOfWeek].push({ ...item, rowspan, used: false });
});

4. 渲染表格,处理rowspan合并

循环时间槽生成表格行,遇到已合并的行直接跳过,避免重复渲染:

const days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];

timeSlots.forEach(slot => {
  const row = document.createElement('tr');
  
  // 插入时间列
  const timeCell = document.createElement('td');
  timeCell.textContent = slot.display;
  row.appendChild(timeCell);

  days.forEach(day => {
    // 检查当前时间槽是否有未渲染的日程
    const targetSchedule = groupedData[day]?.find(item => {
      const itemStartKey = new Date(`2020-01-01T${item.startTime}`).toLocaleTimeString('en-GB', { hour24: true, hour: '2-digit', minute: '2-digit' });
      return itemStartKey === slot.key && !item.used;
    });

    if (targetSchedule) {
      const cell = document.createElement('td');
      cell.textContent = targetSchedule.title;
      cell.rowSpan = targetSchedule.rowspan;
      targetSchedule.used = true;
      cell.style.backgroundColor = '#e8f4f8'; // 可选:添加高亮样式
      row.appendChild(cell);
    } else {
      // 检查当前时间槽是否被已有日程的rowspan覆盖
      const isCovered = groupedData[day]?.some(item => {
        const itemStart = new Date(`2020-01-01T${item.startTime}`);
        const itemEnd = new Date(`2020-01-01T${item.endTime}`);
        const currentSlotTime = new Date(`2020-01-01T${slot.key}`);
        return currentSlotTime > itemStart && currentSlotTime < itemEnd;
      });
      if (!isCovered) {
        row.appendChild(document.createElement('td'));
      }
    }
  });

  tbody.appendChild(row);
});

关键排查点

  • 时间格式统一:确保JSON中startTime/endTime为HH:mm格式,和JS生成的timeKey格式一致,避免匹配失败。
  • DOM加载时机:将JS代码放在DOMContentLoaded事件中,确保页面元素加载完成后再执行:
document.addEventListener('DOMContentLoaded', () => {
  // 所有JS逻辑放在这里
});
  • 控制台打印groupedData,确认数据分组和rowspan计算是否正确。

内容的提问来源于stack exchange,提问作者Carlmalone Mabiog

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:48:13