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

如何为支持动态日期的JS倒计时同步显示对应事件标题

动态赛事倒计时标题同步实现

思路选型

优先用「把事件标题存在现有日程数组里」的方案。比起单独写switch存标题的方式,这个方案不用额外维护标题和索引的对应关系,之后加新赛事只要往日程数组里加一行配置就行,不会出现分支逻辑和数组内容对不上的情况,改起来更省事。

现有代码的问题

  • 重复遍历schedule数组2次,会触发2次initializeClock调用,同时启动多个倒计时计时器,导致页面倒计时数字刷新错乱
  • 循环外部取到的变量i是for循环跑完全程后的全局残留值,根本不是当前匹配到的赛事对应的索引,后面switch语句拿到的索引值完全不准
  • 没有把匹配到的赛事标题同步写到DOM节点里,页面的赛事标题展示区域一直是空的

修改后可直接运行的完整代码

<div>
  Next Race<br>
  <span class="nextRace"></span>
</div>

<div id="clockdiv">
  <span class="race title"></span> Days: <span class="days"></span><br> 
  Hours: <span class="hours"></span><br> 
  Minutes: <span class="minutes"></span><br> 
  Seconds: <span class="seconds"></span>
</div>
const schedule = [
  ['Feb 25 2021', 'Feb 9 2021', "race 1"],
  ['Feb 9 2021', 'Apr 20 2021', "race 2"],
  ['Apr 20 2022', 'Jul 25 2023', "race 3"]
];

function getTimeRemaining(endtime) {
  const total = Date.parse(endtime) - Date.parse(new Date());
  const seconds = Math.floor((total / 1000) % 60);
  const minutes = Math.floor((total / 1000 / 60) % 60);
  const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
  const days = Math.floor(total / (1000 * 60 * 60 * 24));

  return { total, days, hours, minutes, seconds };
}

function initializeClock(id, endtime, raceTitle) {
  const clock = document.getElementById(id);
  const daysSpan = clock.querySelector('.days');
  const hoursSpan = clock.querySelector('.hours');
  const minutesSpan = clock.querySelector('.minutes');
  const secondsSpan = clock.querySelector('.seconds');
  // 同步更新两处标题展示
  document.querySelector('.nextRace').innerHTML = raceTitle;
  clock.querySelector('.race.title').innerHTML = raceTitle;

  function updateClock() {
    const t = getTimeRemaining(endtime);
    daysSpan.innerHTML = t.days;
    hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
    minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
    secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

    if (t.total <= 0) clearInterval(timeinterval);
  }

  updateClock();
  const timeinterval = setInterval(updateClock, 1000);
}

// 合并重复的遍历逻辑,只做一次时间匹配
for (let i = 0; i < schedule.length; i++) {
  const [startDate, endDate, raceTitle] = schedule[i];
  const startMs = Date.parse(startDate);
  const endMs = Date.parse(endDate);
  const currentMs = Date.parse(new Date());

  // 匹配当前时间落在有效区间内的赛事
  if (endMs > currentMs && currentMs >= startMs) {
    initializeClock('clockdiv', endDate, raceTitle);
  }
}

调整说明

  • 删掉了原来冗余的switch语句,因为标题信息已经存在日程数组的第三个字段里,不需要硬编码映射
  • 把原来两次重复的数组遍历合并成一次,避免多个计时器同时启动造成的数字错乱
  • 给initializeClock函数加了raceTitle入参,匹配到对应赛事时,直接读取数组里存的标题值,同步更新两个展示位置的内容
  • 把原来循环里的var换成let,避免变量泄露到全局作用域造成取值异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 18:24:04