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

如何停止并重置运行中的JavaScript倒计时定时器?

嘿,我看你遇到了定时器重复运行的麻烦——每次点击按钮,旧的倒计时定时器没被停止,新的又开始跑,多个定时器同时更新页面内容,自然就乱套了。我来帮你搞定这个问题!

问题根源

你之前把定时器的引用变量x放在了setTimer函数的局部作用域里,每次调用setTimer都会创建一个全新的x变量,之前的定时器就变成了“没人管的孤儿”,根本没法被清除,所以会一直运行下去。

解决方案

我们只需要把定时器的引用提到全局作用域,每次点击按钮时先清除之前的定时器,再创建新的就行。下面是修改好的完整代码:

<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
 p { text-align: center; font-size: 60px; margin-top: 0px; }
</style>
</head>
<body>
<input type='text' value='1490028077' id='timestamp'>&nbsp;
<input type='button' id='convert' value='Convert' onclick='setTimer()'>
<br><br>
<span id='datetime'></span>
<p id="demo"></p>

<script>
// 把定时器引用放到全局,这样每次点击都能拿到它
let countdownTimer = null;

function setTimer() {
  // 先停掉之前的定时器(如果有的话)
  if (countdownTimer) {
    clearInterval(countdownTimer);
  }

  const timeSpan = convert();
  const countDownDate = new Date(timeSpan).getTime();

  // 创建新定时器,把引用存到全局变量里
  countdownTimer = setInterval(function() {
    const now = new Date().getTime();
    const distance = countDownDate - now;

    const days = Math.floor(distance / (1000 * 60 * 60 * 24));
    const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    const seconds = Math.floor((distance % (1000 * 60)) / 1000);

    document.getElementById("demo").innerHTML = `${days}d ${hours}h ${minutes}m ${seconds}s `;

    if (distance < 0) {
      clearInterval(countdownTimer);
      document.getElementById("demo").innerHTML = "EXPIRED";
      // 结束后把引用清空,更规范
      countdownTimer = null;
    }
  }, 1000);
}

function convert() {
  const now = new Date()
  let secondsSinceEpoch = Math.round(now.getTime() / 1000)
  let unixtimestamp = document.getElementById('timestamp').value;
  unixtimestamp = parseInt(unixtimestamp);
  secondsSinceEpoch = parseInt(secondsSinceEpoch);
  unixtimestamp = unixtimestamp + secondsSinceEpoch;

  const months_arr = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  const date = new Date(unixtimestamp*1000);
  const year = date.getFullYear();
  const month = months_arr[date.getMonth()];
  const day = date.getDate();
  const hours = date.getHours();
  let minutes = "0" + date.getMinutes();
  let seconds = "0" + date.getSeconds();

  const convdataTime = `${month} ${day}, ${year} ${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}`;
  document.getElementById('datetime').innerHTML = convdataTime;
  return convdataTime;
}
</script>
</body>
</html>

关键改动说明

  1. 全局定时器变量:新增了全局的countdownTimer变量,用来保存当前运行的定时器引用,这样每次点击按钮都能找到之前的定时器。
  2. 清除旧定时器:每次调用setTimer时,先检查countdownTimer是否存在,如果有就用clearInterval停掉它,确保同一时间只有一个定时器在工作。
  3. 定时器结束后置空:当倒计时到期时,除了清除定时器,还把countdownTimer设为null,避免后续重复清除无效的定时器(虽然clearInterval传无效ID不会报错,但这样做更严谨)。

这样修改后,你每次点击按钮都会先停止之前的倒计时,然后基于新输入的数值重新开始计算,完全符合你的需求啦!

内容的提问来源于stack exchange,提问作者חיים חדד

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:23