FullCalendar通过Ajax传递上月/下月值按月获取事件数据问题
嘿,我来帮你搞定这两个问题!
1. 修复start/end时间范围不符的问题
首先得搞清楚FullCalendar月视图的时间逻辑:月视图的start是当前视图月份的第一天00:00:00,end是下一个月的第一天00:00:00(这样才能覆盖当月所有日期的事件)。你现在看到的奇怪日期,大概率是时区不匹配或者时间戳转日期时的格式问题。
解决步骤:
- 统一前后端时区:在PHP开头加上时区设置(换成你实际需要的时区),比如:
FullCalendar可以设置date_default_timezone_set('Asia/Shanghai');timezone: 'local'来和系统时区保持一致。 - 避免时间戳转译问题:直接把
start和end转成YYYY-MM-DD格式传递,不用依赖unix()时间戳。修改前端请求参数:
后端直接接收字符串即可,不用再转时间戳:data: { start: start.format('YYYY-MM-DD'), end: end.format('YYYY-MM-DD'), month_year: currentMonthYear }$start_dd = $_GET['start']; $end_dd = $_GET['end'];
2. 正确传递当前月份到后端
你用点击按钮取标题文本的方式不可靠——点击按钮时视图还没切换完成,取到的是旧标题;而且标题格式会随版本/语言变化,不好解析。正确做法是用FullCalendar的视图渲染事件来获取当前年月。
修改后的完整前端代码:
// 全局变量存储当前年月,避免DOM操作延迟 let currentMonthYear = ''; $('#calendar1').fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month' }, defaultDate: '<?php echo date('Y-m-d'); ?>', navLinks: true, editable: true, eventLimit: true, showNonCurrentDates: false, timezone: 'local', // 统一时区 // 视图渲染完成时自动获取当前年月 viewRender: function(view, element) { // 格式为YYYY-MM,方便后端筛选 currentMonthYear = view.start.format('YYYY-MM'); // 如果需要和标题一样的格式(比如"May 2024"),用view.title即可 // currentMonthYear = view.title; }, events: function( start, end, timezone, callback ) { $.ajax({ url: 'load_events.php', dataType: 'json', data: { start: start.format('YYYY-MM-DD'), end: end.format('YYYY-MM-DD'), month_year: currentMonthYear }, success: function(doc) { console.log(doc); var events = []; $(doc).each(function() { events.push({ title: this.title, start: this.start }); }); callback(events); } }); }, });
如果你用的是FullCalendar v4及以上版本,
viewRender已经被datesRender替代,写法改成:datesRender: function(info) { currentMonthYear = info.view.currentStart.format('YYYY-MM'); }
调整后的后端PHP代码:
<?php include('../config.php'); date_default_timezone_set('Asia/Shanghai'); // 匹配前端时区 $start = $_GET['start']; $end = $_GET['end']; $month_year = $_GET['month_year']; // 这里可以根据$month_year筛选当月事件,比如: // $sql = "SELECT * FROM events WHERE DATE_FORMAT(start, '%Y-%m') = ?"; // 用预处理语句避免SQL注入 $data = array(); $data[] = array( 'id' => 1, 'title' => date('Y-m-d').'-'.$start.'-'.$end.'-'.$month_year, 'start' => date('Y-m-d'), 'end' => date('Y-m-d'), ); echo json_encode($data); ?>
测试时可以在viewRender里加console.log(currentMonthYear),确认切换月份时变量是否正确更新,这样就能保证每次请求都传递了当前视图的月份啦!
内容的提问来源于stack exchange,提问作者sardhar_test m
相关产品推荐
相关产品推荐

