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
相关产品推荐
相关产品推荐

