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

Evo Calendar日期事件点覆盖问题及代码优化咨询

解决Evo Calendar事件点显示问题及代码优化指导

一、处理Evo Calendar事件点覆盖日期的问题

方案1:限制显示事件点数量,添加“更多”提示

针对日均15个事件的场景,我们可以只显示前2个事件点,再添加标记提示剩余数量,避免覆盖日期:

  1. 添加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; /* 给"更多"标记预留空间 */
}
  1. 添加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;
}

二、代码批评与优化指导

原代码存在的核心问题:

  1. 数据库操作无错误处理:mysqli_query执行失败时无任何提示,会导致页面空白或报错。
  2. 日期循环逻辑错误:date.setDate会修改原始startDate对象,导致后续循环异常。
  3. 不必要的事件拆分:Evo Calendar原生支持跨天事件,手动拆分成每天事件会增加数据量和渲染压力。
  4. JSON输出不安全:直接json_encode输出,若事件名称含特殊字符可能引发XSS或渲染错误。
  5. 内联事件绑定:onclick写在HTML中,不符合关注点分离原则,不利于维护。
  6. 调试代码未清理:生产环境保留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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:37:17