Evo Calendar日期事件点覆盖问题及代码优化咨询
解决Evo Calendar事件点显示问题及代码优化指导
一、处理Evo Calendar事件点覆盖日期的问题
方案1:限制显示事件点数量,添加“更多”提示
针对日均15个事件的场景,我们可以只显示前2个事件点,再添加标记提示剩余数量,避免覆盖日期:
- 添加CSS样式:
/* 隐藏超过2个的事件点 */ .calendar-day .calendar-events .type-bullet:nth-child(n+3) { display: none; } /* 添加"更多"标记 */ .calendar-day.has-more-events .calendar-events::after { content: attr(data-count); position: absolute; bottom: 2px; right: 2px; font-size: 10px; background: #666; color: white; border-radius: 50%; width: 14px; height: 14px; display: flex; align-items: center; justify-content: center; } .calendar-day .calendar-events { position: relative; min-height: 16px; /* 给"更多"标记预留空间 */ }
- 添加JavaScript逻辑(日历初始化后执行):
// 初始化时处理日期单元格 $('#calendar .calendar-day').each(function() { const bulletCount = $(this).find('.type-bullet').length; if (bulletCount > 2) { $(this).find('.calendar-events').attr('data-count', `+${bulletCount - 2}`); $(this).addClass('has-more-events'); } }); // 切换月份后重新处理(日历动态渲染) $('#calendar').on('rendered.evoCalendar', function() { $('#calendar .calendar-day').each(function() { const bulletCount = $(this).find('.type-bullet').length; const eventsContainer = $(this).find('.calendar-events'); if (bulletCount > 2) { eventsContainer.attr('data-count', `+${bulletCount - 2}`); $(this).addClass('has-more-events'); } else { eventsContainer.removeAttr('data-count'); $(this).removeClass('has-more-events'); } }); });
方案2:调整事件点排列方式避免覆盖
如果不想限制显示数量,可修改布局让事件点换行或缩小尺寸:
/* 让事件点换行显示 */ .calendar-day .calendar-events { display: flex; flex-wrap: wrap; gap: 1px; justify-content: flex-start; align-items: center; padding: 2px; } /* 缩小事件点尺寸 */ .calendar-day .type-bullet { width: 6px; height: 6px; margin: 0 !important; /* 去掉默认margin */ } /* 调整日期数字位置,留出更多空间 */ .calendar-day .calendar-day-number { position: relative; z-index: 1; margin-bottom: 18px; }
二、代码批评与优化指导
原代码存在的核心问题:
- 数据库操作无错误处理:
mysqli_query执行失败时无任何提示,会导致页面空白或报错。 - 日期循环逻辑错误:
date.setDate会修改原始startDate对象,导致后续循环异常。 - 不必要的事件拆分:Evo Calendar原生支持跨天事件,手动拆分成每天事件会增加数据量和渲染压力。
- JSON输出不安全:直接
json_encode输出,若事件名称含特殊字符可能引发XSS或渲染错误。 - 内联事件绑定:
onclick写在HTML中,不符合关注点分离原则,不利于维护。 - 调试代码未清理:生产环境保留
console.log会泄露数据。
优化后的代码:
<?php include('db_connect.php'); $events = []; try { // 用预处理语句防SQL注入 $sql = "SELECT id, name, start_date, end_date FROM booking"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if ($result) { $events = mysqli_fetch_all($result, MYSQLI_ASSOC); } } catch (Exception $e) { // 生产环境建议记录日志,不要直接输出错误 error_log("Database error: " . $e->getMessage()); } finally { mysqli_close($conn); } ?> <!DOCTYPE html> <html> <head> <title>My Evo Calendar</title> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/evo-calendar@1.1.2/evo-calendar/css/evo-calendar.min.css"> <style> .header { display: flex; align-items: center; justify-content: space-between; padding: 10px; background-color: #f2f2f2; gap: 10px; /* 用gap替代margin-right,布局更灵活 */ } .header-link { text-decoration: none; color: #333; font-weight: bold; } .add-button { background-color: #4caf50; color: #fff; border: none; padding: 10px 20px; font-size: 16px; cursor: pointer; border-radius: 4px; transition: background-color 0.2s; } .add-button:hover { background-color: #43a047; } /* 可选:事件点优化样式 */ .calendar-day .calendar-events { display: flex; flex-wrap: wrap; gap: 1px; padding: 2px; } .calendar-day .type-bullet { width: 6px; height: 6px; margin: 0 !important; } </style> </head> <body> <div class="header"> <a href="/" class="header-link">Home</a> <button class="add-button" id="addEventBtn">Add Event</button> </div> <div id="calendar"></div> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/evo-calendar@1.1.2/evo-calendar/js/evo-calendar.min.js"></script> <script> // 分离事件绑定,符合关注点分离 document.getElementById('addEventBtn').addEventListener('click', function() { window.location.href = "../dateSelect.php"; }); $(document).ready(function() { // 安全输出JSON,转义HTML特殊字符 var events = <?php echo json_encode($events, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); ?>; // 转换为Evo Calendar兼容的事件格式 var calendarEvents = events.map(function(event) { return { id: event.id, name: event.name, start: event.start_date, end: event.end_date, color: '#ffcc80' }; }); // 初始化日历,利用原生跨天事件支持 $('#calendar').evoCalendar({ calendarEvents: calendarEvents }); // 若使用方案1的"更多"提示,保留以下代码 $('#calendar').on('rendered.evoCalendar', function() { $('#calendar .calendar-day').each(function() { const bulletCount = $(this).find('.type-bullet').length; const eventsContainer = $(this).find('.calendar-events'); if (bulletCount > 2) { eventsContainer.attr('data-count', `+${bulletCount - 2}`); $(this).addClass('has-more-events'); } else { eventsContainer.removeAttr('data-count'); $(this).removeClass('has-more-events'); } }); }); }); </script> </body> </html>
优化要点说明:
- 数据库安全:使用预处理语句防SQL注入,添加异常捕获处理错误。
- 逻辑简化:直接利用Evo Calendar的跨天事件支持,避免手动拆分事件。
- 安全输出:JSON转义特殊字符,防止XSS攻击和渲染错误。
- 代码规范:移除内联事件绑定,改用JS事件监听,符合关注点分离。
- UI优化:添加hover效果、圆角等提升视觉体验,用
gap替代margin更现代。
内容的提问来源于stack exchange,提问作者simontheguitarist
相关产品推荐
相关产品推荐

