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

JavaScript多秒表无法并行计时问题修复咨询

问题原因

多秒表无法并行计时的核心bug是所有秒表共用全局的time计时变量和running状态变量:

  • 启动新秒表时会直接修改全局running为1,覆盖其他运行中秒表的状态,导致旧秒表的递归计时逻辑被中断
  • 全局time变量只有一份,新秒表启动时会直接读取当前全局time的数值,自然会从其他秒表的累计时长开始计数
  • 原有逻辑没有区分不同秒表的定时器,暂停操作会无差别终止所有秒表的计时循环
修复后完整代码
// 按秒表ID独立存储每个秒表的状态,互不干扰
const stopwatchMap = {};

// 新增秒表行渲染逻辑(修复重置按钮重复ID问题)
var row_id = $('#hidden_row_id').val();
output = '<td>' + name +
  ' <input type="hidden" name="hidden_name[]" id="name' + row_id +
  '" class="name" value="' + name + '" /></td>';
output += '<td><span id="output' + row_id + '">00:00:00</span> <input type="hidden" name="hidden_time[]" id="time' + row_id +
  '" value=""/></td>';
output +=
  '<td><button type="button" name="remove_details" class="btn remove_details" id="' +
  row_id + '"><i class="fa fa-times"></i></button></td>';
output +=
  '<td><a class="btn" id ="startPause' + row_id + '" onClick="startPause(' + row_id + ')"><i class="fa fa-play"></i></a><a class="btn" id="reset'+row_id+'" onClick="reset(' + row_id + ')"><i class="fa fa-refresh"></i></a></td>';
$('#row_' + row_id + '').html(output);

// 初始化当前新秒表的独立状态
stopwatchMap[row_id] = {
  time: 0,
  running: false,
  timer: null
};

function startPause(i) {
  const current = stopwatchMap[i];
  if (!current.running) {
    current.running = true;
    increment(i);
    document.getElementById(`startPause${i}`).innerHTML = "<i class='fa fa-pause'></i>";
  } else {
    current.running = false;
    clearTimeout(current.timer);
    document.getElementById(`startPause${i}`).innerHTML = "<i class='fa fa-play'></i>";
  }
}

function reset(i) {
  const current = stopwatchMap[i];
  current.running = false;
  current.time = 0;
  clearTimeout(current.timer);
  document.getElementById(`startPause${i}`).innerHTML = "<i class='fa fa-play'></i>";
  document.getElementById(`output${i}`).innerHTML = "00:00:00";
  document.getElementById(`time${i}`).value = "00:00:00";
}

function increment(i) {
  const current = stopwatchMap[i];
  if (current.running) {
    current.timer = setTimeout(function() {
      current.time++;
      const mins = String(Math.floor(current.time / 10 / 60)).padStart(2, '0');
      const secs = String(Math.floor(current.time / 10 % 60)).padStart(2, '0');
      const tenths = current.time % 10;
      const timeStr = `${mins}:${secs}:0${tenths}`;
      document.getElementById(`output${i}`).innerHTML = timeStr;
      document.getElementById(`time${i}`).value = timeStr;
      increment(i);
    }, 100);
  }
}

对应的HTML依赖:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
关键修改点
  • 废弃全局共享的time、running变量,用stopwatchMap按秒表唯一ID分别存储每个秒表的计时值、运行状态、定时器实例
  • 暂停、重置操作只会清除当前操作秒表对应的定时器,不会影响其他正在运行的秒表
  • 修复原代码中所有重置按钮ID重复的问题,避免DOM查询冲突
  • 用padStart简化了补零逻辑,代码更简洁

实现效果参考:
多秒表运行效果截图

内容的提问来源于stack exchange,提问作者Md. Nahid Hasan Tamim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:51:21