基于Moment JS的日期选择器次日切换功能异常求助
解决你的日期选择器点击Next异常问题
嘿,我瞅了你的代码,发现问题根源在Moment.js的可变对象特性上!咱们一步步捋清楚:
问题出在哪?
Moment.js的日期对象是可变的——你调用subtract()或add()时,会直接修改原对象本身,而不是返回新的日期对象。这就导致了点击Next时的计算混乱:
- 点击
next-day后,你先把currentDate加1天(比如从26号变27号) - 进入
tracker_picker_update函数,先把当前日期设为27号 - 然后调用
currentDate.subtract(1, "day"),这会把原currentDate又改回26号,用来设置前一天 - 接着调用
currentDate.add(1, "day"),日期又回到27号,这时候设置的后一天就变成了27号,而不是预期的28号!
点击Prev时看似正常,其实也是有隐患的,只是刚好流程没暴露问题而已。
修复方案
核心思路是:不要直接修改原日期对象,基于副本做计算。Moment.js提供了clone()方法来创建日期副本,这样所有加减操作都在副本上进行,不会污染原变量。
修复后的完整代码如下:
HTML部分(无需修改)
<div class="tracker-day-picker"> <div class="adjacent-day previous-day"><span>Prev</span></div> <div class="day current-day"><span>Current</span></div> <div class="adjacent-day next-day"><span>Next</span></div> </div>
JavaScript修复版
$(document).ready(function(){ var currentDate = moment(); tracker_picker_update( currentDate ); $(".previous-day").on("click", function(){ currentDate = currentDate.subtract(1, "day"); tracker_picker_update( currentDate ); }); $(".next-day").on("click", function(){ currentDate = currentDate.add(1, "day"); tracker_picker_update( currentDate ); }); }); function tracker_picker_update( currentDate ) { var tracker_picker = $(".tracker-day-picker"); // 克隆当前日期对象,避免修改原变量 var dateCopy = currentDate.clone(); // 设置当前日期(用Do格式符显示序数词:25th、26th) tracker_picker.find(".current-day span").text( currentDate.format("Do MMM YYYY") ); // 设置前一天:基于副本减1天 tracker_picker.find(".previous-day span").text( dateCopy.subtract(1, "day").format("Do MMM YYYY") ); // 重新克隆原日期,计算后一天 dateCopy = currentDate.clone(); tracker_picker.find(".next-day span").text( dateCopy.add(1, "day").format("Do MMM YYYY") ); return true; }
关键修改点说明
- 用
currentDate.clone()创建日期副本,所有加减操作都在副本上执行,保证原currentDate的准确性 - 替换日期格式符为
Do,实现你需要的序数词显示(比如25th、26th) - 计算后一天时重新克隆原日期,避免前一次的减法操作影响结果
内容的提问来源于stack exchange,提问作者Deepak Kamat
相关产品推荐
相关产品推荐

