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

AJAX加载数据后FullCalendar插件无法在指定div中显示的问题

解决FullCalendar无法渲染设备专属预订日历的问题

以下是针对你的问题的排查方向和具体修正方案,直接落地解决:


1. 先确认fetch_data.php返回的JSON格式完全符合FullCalendar要求

FullCalendar对事件数据有严格格式要求,核心字段必须正确:

  • 必填:title(事件显示文本)、start(开始时间,需为ISO8601格式:YYYY-MM-DD或YYYY-MM-DDTHH:mm:ss)
  • 可选:end(结束时间,注意FullCalendar的end是排他时间,若预订到当天结束,需在数据库日期基础上加1天)、color(自定义事件颜色)

修正后的fetch_data.php示例:

<?php
// 连接数据库(请替换为你的数据库配置)
$conn = mysqli_connect('localhost', 'user', 'password', 'db_name');
if (!$conn) die('数据库连接失败');

// 获取前端传递的设备名称参数
$deviceName = mysqli_real_escape_string($conn, $_GET['device_name'] ?? '');

// 查询该设备的预订数据
$query = "SELECT start_date, end_date, booker FROM bookings WHERE device_name = '$deviceName'";
$result = mysqli_query($conn, $query);

$events = [];
while ($row = mysqli_fetch_assoc($result)) {
    $events[] = [
        'title' => '已预订:' . $row['booker'],
        'start' => date('Y-m-d', strtotime($row['start_date'])),
        // 处理结束时间:若预订到当日结束,需加1天才能在日历上显示完整日期
        'end' => date('Y-m-d', strtotime($row['end_date'] . ' +1 day')),
        'color' => '#ff4444' // 自定义红色标识已预订
    ];
}

// 输出纯JSON,禁止任何多余输出(比如调试echo、空格)
header('Content-Type: application/json');
echo json_encode($events);
mysqli_close($conn);
exit;

关键注意:确保fetch_data.php没有输出任何非JSON内容(比如调试信息、PHP错误提示),否则前端JSON解析会失败,日历直接不渲染。


2. 确保AJAX请求正确传递设备参数+日历容器唯一

每个设备的日历容器必须有唯一标识,避免多个设备共用同一个DOM ID导致覆盖;同时要确保AJAX请求正确携带当前设备名称。

修正后的index.php前端代码示例:

<!DOCTYPE html>
<html>
<head>
    <!-- 加载FullCalendar依赖(以v5.x为例,无需jQuery) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.css">
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js"></script>
    <style>
        .device-item { display: flex; margin: 20px 0; gap: 20px; }
        .device-card { width: 300px; border: 1px solid #ddd; padding: 15px; }
        .calendar-container { flex: 1; border: 1px solid #ddd; padding: 15px; }
    </style>
</head>
<body>
    <!-- 设备列表与日历容器 -->
    <div class="device-list">
        <?php
        // 示例:从数据库查询设备详情
        $devices = [
            ['name' => '会议室投影仪', 'desc' => '支持1080P投影'],
            ['name' => '移动工作站', 'desc' => '高性能图形处理']
        ];
        foreach ($devices as $idx => $device) {
            $deviceId = 'device-' . $idx;
            $calendarId = 'calendar-' . $idx;
        ?>
        <div class="device-item">
            <div class="device-card" data-device-id="<?php echo $idx; ?>" data-device-name="<?php echo htmlspecialchars($device['name']); ?>">
                <h3><?php echo htmlspecialchars($device['name']); ?></h3>
                <p><?php echo htmlspecialchars($device['desc']); ?></p>
                <button class="show-calendar">查看预订日历</button>
            </div>
            <div class="calendar-container" id="<?php echo $calendarId; ?>"></div>
        </div>
        <?php } ?>
    </div>

    <script>
        // 绑定设备卡片点击事件
        document.querySelectorAll('.show-calendar').forEach(btn => {
            btn.addEventListener('click', function() {
                const deviceCard = this.closest('.device-card');
                const deviceName = deviceCard.dataset.deviceName;
                const calendarId = deviceCard.closest('.device-item').querySelector('.calendar-container').id;
                const calendarEl = document.getElementById(calendarId);

                // 清空容器,避免重复初始化
                calendarEl.innerHTML = '';

                // 发起AJAX请求
                fetch(`fetch_data.php?device_name=${encodeURIComponent(deviceName)}`)
                    .then(response => {
                        if (!response.ok) throw new Error('请求失败');
                        return response.json();
                    })
                    .then(events => {
                        // 初始化FullCalendar v5.x
                        new FullCalendar.Calendar(calendarEl, {
                            headerToolbar: {
                                left: 'prev,next today',
                                center: 'title',
                                right: 'dayGridMonth,timeGridWeek'
                            },
                            events: events,
                            locale: 'zh-cn' // 设置中文显示
                        }).render(); // 必须调用render()渲染日历
                    })
                    .catch(error => {
                        console.error('加载日历失败:', error);
                        calendarEl.innerHTML = '<p>加载预订数据失败,请稍后重试</p>';
                    });
            });
        });
    </script>
</body>
</html>

3. 快速排查的调试技巧

  1. 查看AJAX请求状态:打开浏览器F12→Network标签,查看fetch_data.php的请求:
    • 状态码需为200 OK
    • Response标签查看返回内容是否为合法JSON(无语法错误)
  2. 检查JS控制台错误:F12→Console标签,排查是否有依赖未加载(比如FullCalendar未找到)、DOM元素不存在等错误
  3. 验证数据格式:在AJAX的then回调里打印console.log(events),确认数据结构符合FullCalendar要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:13:17