You need to enable JavaScript to run this app. 为什么JavaScript中多次使用timer计时器仅第一个正常工作?
优惠活动
大模型
产品
解决方案
定价
更多

为什么JavaScript中多次使用timer计时器仅第一个正常工作?

问题根因

  • 原代码使用固定ID定位元素,HTML规范中同一页面ID不能重复,导致后续计时器找不到对应渲染节点
  • 全局变量存储截止时间、定时器实例,新增计时器时会覆盖之前的变量,仅最后一个定时器的逻辑能生效

修复方案

1. 调整CSS

把原来ID选择器的样式改成类选择器,其他样式保持不变:

/*time start*/
.timer {
  font-family: sans-serif;
  color: #fff;
  display: inline-block;
  font-weight: 100;
  text-align: center;
  font-size: 16px;
  margin-right: 40px; /* 多个计时器之间的间距 */
}
.timer div {
  border-radius: 20px;
  background: #000000f7;
  display: inline-block;
  font-family: Oswald;
  font-size: 52px;
  font-weight: 400;
  width: 96px;
  margin-right: 11px;
}
.timer .smalltext {
  color: #ffffff;
  font-size: 19px;
  font-family: Poppins;
  font-weight: 500;
  display: block;
  padding: 0;
  width: auto;
  margin-top: -11px;
}
.timer .time-up { /* 把原ID选择器改为类选择器 */
  margin: 8px 0 0;
  text-align: left;
  font-size: 14px;
  font-style: normal;
  color: #000000;
  font-weight: 500;
  letter-spacing: 1px;
}
.delas {
  display: inline-block;
  font-size: 23px;
  padding-right: 31px;
}
/*time end*/

2. 重写JS逻辑,封装为多实例构造函数

// 计时器构造函数
function CountdownTimer(containerSelector, deadlineStr) {
  this.container = document.querySelector(containerSelector);
  if (!this.container) return;
  this.deadline = new Date(deadlineStr).getTime();
  // 仅查找当前计时器容器下的节点,避免和其他计时器冲突
  this.dayEl = this.container.querySelector('.day');
  this.hourEl = this.container.querySelector('.hour');
  this.minuteEl = this.container.querySelector('.minute');
  this.secondEl = this.container.querySelector('.second');
  this.timeUpEl = this.container.querySelector('.time-up');
  
  // 启动当前计时器
  this.start = function() {
    const _this = this;
    this.timer = setInterval(function () {
      const currentTime = new Date().getTime();
      const t = _this.deadline - currentTime;
      const days = Math.floor(t / (1000 * 60 * 60 * 24));
      const hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      const minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = Math.floor((t % (1000 * 60)) / 1000);
      
      _this.dayEl.innerHTML = days;
      _this.hourEl.innerHTML = hours;
      _this.minuteEl.innerHTML = minutes;
      _this.secondEl.innerHTML = seconds;
      
      if (t < 1) {
        clearInterval(_this.timer);
        _this.timeUpEl.innerHTML = "";
        _this.dayEl.innerHTML = "0";
        _this.hourEl.innerHTML = "0";
        _this.minuteEl.innerHTML = "0";
        _this.secondEl.innerHTML = "0";
      }
    }, 1000);
  }
  this.start();
}

// 初始化多个计时器,传入对应容器选择器和截止时间即可,可无限新增
new CountdownTimer('#timer1', "june 07, 2021, 07:49:25");
new CountdownTimer('#timer2', "july 15, 2024, 12:00:00");
new CountdownTimer('#timer3', "august 20, 2024, 18:30:00");

3. 编写对应HTML结构

<!-- 第一个计时器 -->
<div class="timer" id="timer1">
  <div><span class="day"></span><span class="smalltext">天</span></div>
  <span class="delas">:</span>
  <div><span class="hour"></span><span class="smalltext">时</span></div>
  <span class="delas">:</span>
  <div><span class="minute"></span><span class="smalltext">分</span></div>
  <span class="delas">:</span>
  <div><span class="second"></span><span class="smalltext">秒</span></div>
  <div class="time-up"></div>
</div>

<!-- 第二个计时器 -->
<div class="timer" id="timer2">
  <div><span class="day"></span><span class="smalltext">天</span></div>
  <span class="delas">:</span>
  <div><span class="hour"></span><span class="smalltext">时</span></div>
  <span class="delas">:</span>
  <div><span class="minute"></span><span class="smalltext">分</span></div>
  <span class="delas">:</span>
  <div><span class="second"></span><span class="smalltext">秒</span></div>
  <div class="time-up"></div>
</div>

<!-- 第三个计时器 -->
<div class="timer" id="timer3">
  <div><span class="day"></span><span class="smalltext">天</span></div>
  <span class="delas">:</span>
  <div><span class="hour"></span><span class="smalltext">时</span></div>
  <span class="delas">:</span>
  <div><span class="minute"></span><span class="smalltext">分</span></div>
  <span class="delas">:</span>
  <div><span class="second"></span><span class="smalltext">秒</span></div>
  <div class="time-up"></div>
</div>

后续需要新增计时器时,只需要新增对应HTML结构,然后在JS初始化代码中加一行new CountdownTimer(对应容器ID, 截止时间字符串)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 07:54:00