如何在JavaScript中点击按钮时清除未完成动画并重启?
解决动画叠加卡顿问题
原动画实现了红色方块沿黄色容器对角线移动的效果,但快速点击按钮时,会出现多个动画叠加导致的卡顿——旧动画未结束就启动新动画,多个定时器同时修改方块位置,造成画面混乱。
修改思路
问题核心在于原代码中定时器id是函数局部变量,每次点击按钮调用myMove()时,新的id变量会覆盖旧的,导致无法清除之前运行的定时器。需要做以下调整:
- 将定时器id变量移到函数外部,确保每次点击都能获取并清除上一次的定时器
- 清除定时器后,立即将方块重置回左上角位置,再启动新动画
修改后的完整代码
<!DOCTYPE html> <html> <style> #container { width: 400px; height: 400px; position: relative; background: yellow; } #animate { width: 50px; height: 50px; position: absolute; background-color: red; } </style> <body> <p><button onclick="myMove()">Click Me</button></p> <div id ="container"> <div id ="animate"></div> </div> <script> // 将定时器id放在函数外部,保存上一次的定时器实例 let animationId = null; function myMove() { const elem = document.getElementById("animate"); // 清除当前运行的动画 clearInterval(animationId); // 重置方块位置到左上角 elem.style.top = "0px"; elem.style.left = "0px"; let pos = 0; // 启动新动画 animationId = setInterval(frame, 5); function frame() { if (pos == 350) { clearInterval(animationId); } else { pos++; elem.style.top = pos + "px"; elem.style.left = pos + "px"; } } } </script> </body> </html>
关键修改点说明
- 把
animationId变量提升到全局作用域,每次点击都能通过它访问到上一次启动的定时器,调用clearInterval(animationId)就能彻底停止旧动画 - 清除定时器后,手动将方块的
top和left设为0px,确保重置到初始位置 - 重置
pos变量为0,保证新动画从起点开始计算位置
内容的提问来源于stack exchange,提问作者Nasser
相关产品推荐
相关产品推荐

