响应式日历中February(Fevrier)月份显示异常问题排查
问题定位与修复
核心问题
全局
dmonth变量被意外修改:在checkDateCalendarLimit函数的循环中,dmonth +=1直接修改了全局的月份追踪变量,导致后续切换时的基准月份完全偏离预期。比如当你试图显示二月相关月份时,全局dmonth已经被循环递增,传入appendCalendar的参数错误,最终导致标题与天数不匹配。月份显示逻辑错误:当
dateCounterLimit为3时,原代码显示的是当前基准月份之后的3个月份,而非你需求的“当前月份前后各一个(共3个)”,同时函数逻辑污染了全局变量。全局日期变量被不当重置:
appendCalendar的else分支中date = new Date()会将全局日期重置为当前系统日期,干扰跨年度月份的年份计算。
修复代码
1. 修正checkDateCalendarLimit函数
不要修改全局dmonth,使用局部变量计算需显示的月份,同时调整为显示当前月份及前后各一个(共3个):
function checkDateCalendarLimit(currentMonth){ if(dateCounterLimit===1){ console.log({currentMonth}) appendCalendar(currentMonth) } else{ // 显示前一个月、当前月、后一个月 for(let i=-1; i<=1; i++){ const targetMonth = currentMonth + i console.log({targetMonth}) appendCalendar(targetMonth) } } }
2. 重写appendCalendar函数
移除全局变量污染,直接通过传入的月份参数计算正确的年月和天数:
function appendCalendar(param){ let wrapper = document.createElement('div') let DateSpanWrapperDiv = document.createElement('div') DateSpanWrapperDiv.className = 'DateSpanWrapperDiv' let month_parag = document.createElement('p') month_parag.className = "the_month" calendar.appendChild(wrapper) wrapper.appendChild(month_parag) wrapper.appendChild(DateSpanWrapperDiv) // 基于传入参数生成目标日期,自动处理超界月份 let targetDate = new Date(year, param, 1) let actualMonth = targetDate.getMonth() let actualYear = targetDate.getFullYear() wrapper.setAttribute('id', `dateWrapper_${actualYear}_${actualMonth}`) wrapper.className = "dateWrapperDiv" // 获取当前月份的最后一天 let lastdate = new Date(actualYear, actualMonth + 1, 0).getDate(); // 设置正确的月份标题 month_parag.innerHTML = `${monthArray[actualMonth]} ${actualYear}` // 生成日期节点 for(let i=1; i<=lastdate; i++){ let dateSpan = document.createElement('span') dateSpan.innerHTML = i DateSpanWrapperDiv.appendChild(dateSpan) } }
3. 移除不必要的全局操作
原代码appendCalendar中else分支的date = new Date()和domth = date.getMonth()已被移除,不再干扰全局状态。
修复效果
- 切换到二月(Fevrier)时,标题会正确显示
Fevrier XXXX,天数为对应年份二月的28或29天。 - 响应式切换正常:小屏显示当前1个月份,大屏显示当前月份及前后各1个,共3个月份。
- 全局变量不再被意外修改,月份追踪逻辑稳定,跨年度切换也能正确显示年份和月份。
内容的提问来源于stack exchange,提问作者Mehdi
相关产品推荐
相关产品推荐

