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

JS日历添加点击监听获取日期及日期颜色显示异常问题咨询

前端日历功能修复方案

1. 日期点击监听实现

因为代码是通过字符串拼接动态生成日期元素的,推荐使用事件委托方案实现点击监听,性能更高且不需要每次渲染日历重复绑定事件:

  • 直接给日历的日期容器.days绑定点击事件,利用事件冒泡机制捕获子元素的点击动作
  • 点击时过滤掉上个月的隐藏日期元素,即可拿到选中的年月日拼接为标准日期格式

2. 日期颜色判断逻辑修复

原有逻辑的缺陷是只比较了日和月两个维度,没有考虑年的维度,也没有处理跨月时日期大小的判断问题:

  • 先获取今日的零点时间戳作为判断基准,排除时分秒对日期比较的干扰
  • 每个待判断的日期都生成对应的Date对象,直接和今日的基准日期比较,自动处理年、月、日的层级判断,避免手动判断多维度的逻辑漏洞

修改后完整JS代码

// 存储今日零点日期作为比较基准
const today = new Date();
today.setHours(0, 0, 0, 0);
const date = new Date();

const renderCalendar = () => {
  date.setDate(1);

  const monthDays = document.querySelector(".days");

  const lastDay = new Date(
    date.getFullYear(),
    date.getMonth() + 1,
    0
  ).getDate(); 

  const prevLastDay = new Date(
    date.getFullYear(),
    date.getMonth(),
    0
  ).getDate(); 

  const firstDayIndex = date.getDay();

  const lastDayIndex = new Date(
    date.getFullYear(),
    date.getMonth() + 1,
    0
  ).getDay();

  const nextDays = 7 - lastDayIndex - 1;

  const months = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ];


  document.querySelector(".date h1").innerHTML = months[date.getMonth()];
  document.querySelector(".date p").innerHTML = new Date().toDateString();

  let days = "";

  for (let x = firstDayIndex; x > 0; x--) {
    days += `<div class="prev-date">${prevLastDay - x + 1}</div>`;
  } 

  for (let i = 1; i <= lastDay; i++) {
    // 生成当前遍历的日期对象,设置为零点避免时间干扰
    const currentItemDate = new Date(date.getFullYear(), date.getMonth(), i);
    currentItemDate.setHours(0, 0, 0, 0);
    if (currentItemDate >= today) {
      days += `<div class="green">${i}</div>`;
    } else {
      days += `<div class="red">${i}</div>`;
    }
  }

  monthDays.innerHTML = days;
};

// 日期点击事件委托绑定
document.querySelector('.days').addEventListener('click', (e) => {
  // 过滤上个月隐藏的日期
  if (e.target.classList.contains('prev-date')) return;
  const selectDay = e.target.innerText.padStart(2, '0');
  const selectMonth = (date.getMonth() + 1).toString().padStart(2, '0');
  const selectYear = date.getFullYear();
  const selectFullDate = `${selectYear}-${selectMonth}-${selectDay}`;
  // 输出选中日期,可在此处添加自定义业务逻辑
  console.log('选中的日期:', selectFullDate);
});

document.querySelector(".prev").addEventListener("click", () => {
  date.setMonth(date.getMonth() - 1);
  renderCalendar();
});

document.querySelector(".next").addEventListener("click", () => {
  date.setMonth(date.getMonth() + 1);
  renderCalendar();
});
renderCalendar();

其他说明

CSS和HTML代码无需修改,可直接沿用原来的代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:24:07