如何在点击set或reset按钮时重置setTimeout定时器,解决多定时器并行问题
问题修复方案
问题根源
- 单个变量存储定时器ID导致历史任务无法清除:你定义的
timer变量会被后续setTimeout的返回值不断覆盖,最终仅保留最后一个定时器的ID,调用clearTimeout时只能清除最后一个定时任务,前3个定时任务依然会正常触发,导致reset功能失效、重复点击set后多任务并行。 - 未清理jQuery动画队列和重置样式:就算定时器被清除,已经触发的
animate动画还会在队列中继续执行,同时没有将段落字号重置为初始状态,导致重置后样式无法复原。 - 原有CSS存在笔误:
color: 000缺少#标识,会导致样式不生效。
修复思路
- 用数组存储所有定时器ID,重置时遍历数组清除全部定时任务
- 重置操作中补充停止所有p元素的动画队列、将字号重置为初始14px的逻辑
- 每次点击set按钮时先执行完整重置逻辑,保证旧任务全部清除后再创建新的定时任务
- 阻止a标签的默认跳转行为,避免点击按钮后页面回到顶部
修复后代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p>first row</p> <p>second row</p> <p>third row</p> <a class="set" href="#">set</a> <a class="reset" href="#">reset</a>
CSS
a { padding: 10px; background-color: #ddd; color: #000; } p { font-size: 14px; }
JavaScript
var timers = []; // 用数组存储所有定时器ID // 封装重置逻辑,复用给set和reset按钮 function resetAll() { // 清除所有定时器 timers.forEach(timer => clearTimeout(timer)); timers = []; // 停止所有p元素的动画,清空动画队列,重置字号为初始值 jQuery('p').stop(true, true).css('fontSize', '14px'); } jQuery(".set").click(function(e) { e.preventDefault(); // 阻止a标签默认跳转 resetAll(); // 先清空旧任务 // 把所有定时器ID存入数组 timers.push(setTimeout(function() { jQuery("p:nth-child(1)").animate({ fontSize: "18px" }, 500); }, 1000)); timers.push(setTimeout(function() { jQuery("p:nth-child(1)").animate({ fontSize: "14px" }, 500); jQuery("p:nth-child(2)").animate({ fontSize: "18px" }, 500); }, 4500)); timers.push(setTimeout(function() { jQuery("p:nth-child(2)").animate({ fontSize: "14px" }, 500); jQuery("p:nth-child(3)").animate({ fontSize: "18px" }, 500); }, 7500)); timers.push(setTimeout(function() { jQuery("p:nth-child(3)").animate({ fontSize: "14px" }, 500); }, 10500)); }); jQuery(".reset").click(function(e) { e.preventDefault(); // 阻止a标签默认跳转 resetAll(); });
内容的提问来源于stack exchange,提问作者Sadegh
相关产品推荐
相关产品推荐

