JavaScript循环使用setTimeout延时切换背景色失效如何解决
问题原因
- 第一个错误:
setTimeout第一个参数需要传入函数引用,你写的setTimeout(changeColor(i), 1000)是直接执行了changeColor(i)并把返回值(也就是undefined)传给了setTimeout,所以所有颜色修改会在循环执行时同步跑完,不会触发延时逻辑。 - 第二个错误:所有定时器的延时都设为了1000ms,就算传对了函数引用,所有修改也会在1秒后同时执行,最终只会显示最后一个色相值对应的颜色。
修复方案
方案1:调整定时器延时+传入函数引用
直接修改原循环逻辑,把延时设置为i * 1000,每个定时器比前一个晚1秒触发,同时把执行逻辑包裹在箭头函数里避免立即执行:
function myLoop() { for (let i = 0; i < 361; i++) { console.log(i); setTimeout(() => changeColor(i), i * 1000); } } function changeColor(hueIndex) { let elem = document.getElementById('bodyId'); elem.style.backgroundColor = `hsl(${hueIndex}, 50%, 50%)`; }
<body id='bodyId'> <button onclick="myLoop();">Click me!</button> </body>
方案2:用setInterval实现(更节省内存,避免一次性创建361个定时器)
如果不想一次性生成大量定时器,可以用计时器逐个触发变色逻辑,还能避免重复点击生成多个计时器冲突:
let hue = 0; let timer = null; function myLoop() { // 重复点击时清除已有定时器 if (timer) clearInterval(timer); hue = 0; changeColor(hue); timer = setInterval(() => { hue++; changeColor(hue); if (hue >= 360) clearInterval(timer); }, 1000) } function changeColor(hueIndex) { let elem = document.getElementById('bodyId'); elem.style.backgroundColor = `hsl(${hueIndex}, 50%, 50%)`; }
内容的提问来源于stack exchange,提问作者Jakub.Novotny
相关产品推荐
相关产品推荐

