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

如何用JavaScript或jQuery在无序列表中创建无限个独立计时器列表项

问题原因
  • 字符串拼接逻辑错误:你在append的字符串模板里把变量i写在了单引号内部,JavaScript不会对单引号内部的变量做解析,最终生成的span id是minutes+i这类无效字符串,不是你预期的minutes0、minutes1,所以后续找不到DOM元素。
  • 变量作用域冲突:setInterval的回调函数引用了全局变量i,等到回调执行时,全局i已经被后续新增的计时器修改,会指向最新的id后缀,无法对应当前计时器的元素。
  • 语法错误:全局变量声明Var i = 0首字母大写不符合JS语法规范,i=++是错误写法,正确递增写法为i++。
  • 执行顺序错误:函数内部嵌套$(document).ready是多余操作,且回调为异步执行,会导致setInterval先启动、元素还未被插入到DOM中,操作不存在的元素直接报错。
  • 重复声明冗余:pad函数不需要每次调用都重新声明,可以提取到全局复用。
正确实现代码
// 全局计数器,用于生成唯一id后缀
let timerCount = 0;
// 公共补零函数
function pad (val) { 
  return val > 9 ? val : "0" + val; 
}

function listTimer() {
  // 存储当前计时器的id后缀,避免受全局变量后续修改影响
  const currentIndex = timerCount;
  let sec = 0;
  // 先插入DOM元素,保证后续能找到
  $("#sortable1").append(`<li class="ui-state-default">
    <span id="minutes${currentIndex}"></span>:<span id="seconds${currentIndex}"></span>
  </li>`);
  // 启动计时器
  setInterval(function(){    
    document.getElementById(`seconds${currentIndex}`).innerHTML = pad(++sec%60);
    document.getElementById(`minutes${currentIndex}`).innerHTML = pad(parseInt(sec/60,10));
  }, 1000);
  // 全局计数器递增,供下一个计时器使用
  timerCount++;
}
补充说明

如果不想用id也可以完全规避id冲突问题,插入元素时直接保存DOM节点引用,不需要通过id查找:

let timerCount = 0;
function pad (val) { 
  return val > 9 ? val : "0" + val; 
}

function listTimer() {
  let sec = 0;
  // 直接创建DOM节点
  const $minSpan = $('<span></span>');
  const $secSpan = $('<span></span>');
  const $li = $('<li class="ui-state-default"></li>').append($minSpan, ':', $secSpan);
  $("#sortable1").append($li);
  setInterval(function(){    
    $secSpan.text(pad(++sec%60));
    $minSpan.text(pad(parseInt(sec/60,10)));
  }, 1000);
  timerCount++;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:36:04