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

使用setInterval方法时MomentJS无法正常工作的求助

解决moment.js动态更新“X分钟前”格式的问题

嘿,你的问题其实很典型——第一次执行更新后,原始的时间戳被覆盖了!

问题根源

当你第一次调用timer函数时,你把<span>里的2018-05-15 09:21:00替换成了类似“5年前”的相对时间文本。等到下一秒setInterval再次执行时,moment()拿到的是这个已经变成相对时间的字符串,根本没法解析成有效的时间,自然就失效了。

解决方案

把原始的时间戳存在元素的data属性里,这样每次计算都能从这个属性获取原始时间,而不是被覆盖后的innerText。


修改后的完整代码

HTML部分

<span class="timeago" data-time="2018-05-15 09:21:00"></span>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>

JavaScript部分

// 定义更新函数:从data属性读取原始时间计算相对格式
let updateTimeAgo = () => {
  const timeElements = document.getElementsByClassName('timeago');
  for(let i = 0; i < timeElements.length; i++) {
    // 从data-time获取原始时间戳,避免被覆盖
    const rawTime = timeElements[i].dataset.time;
    const relativeTime = moment(rawTime, "YYYY-MM-DD h:mm:ss")
                          .tz("Asia/Kathmandu")
                          .fromNow();
    timeElements[i].innerText = relativeTime;
  }
};

// 页面加载后立刻执行一次,避免延迟显示
updateTimeAgo();
// 改为每60秒更新一次:moment的fromNow只有分钟级变化才会更新文本,每秒更新浪费性能
setInterval(updateTimeAgo, 60000);

额外优化说明

  • 调整了定时器间隔为60秒:fromNow()在分钟级以下的变化不会更新显示文本(比如“59秒前”到“1分钟前”才会变化),每秒更新完全没必要,还会消耗不必要的性能。
  • 增加了初始化执行:确保页面加载完成后立刻显示相对时间,不用等1秒才更新。
  • 使用dataset.time读取data属性:这是HTML5标准的用法,比getAttribute更简洁直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:49:36