如何通过定时器逐个修改.led类下所有<div>的opacity样式?
LED灯逐个亮起问题的解决方案
你的代码没法正常工作主要有两个关键问题,咱们一步步拆解:
问题分析
var变量的作用域陷阱:用var声明的i是函数级作用域,当setTimeout的回调函数执行时,循环已经全部跑完了,此时i的值等于leds.length(也就是3),leds[3]是不存在的,所以找不到对应的DOM元素。- 延迟时间设置错误:所有
setTimeout都设置了1000ms延迟,这会导致所有回调在1秒后同时执行,没法实现“每隔1秒逐个亮起”的效果。
修复方案
下面给你几种可行的解决办法,选你顺手的用就行:
方案1:用let替代var(ES6+推荐)
let有块级作用域,循环的每次迭代都会创建一个新的i绑定,确保每个回调拿到的都是当前迭代的正确索引,同时调整延迟时间实现逐个间隔亮起:
var leds = $(".led"); for (let i = 0; i < leds.length; i++) { setTimeout(function () { $(leds[i]).css('opacity', '1'); }, 1000 * (i + 1)); // 第一个1秒后亮,第二个2秒,以此类推 }
方案2:用闭包保存索引(兼容旧浏览器)
如果需要兼容不支持ES6的环境,可以用立即执行函数(IIFE)创建闭包,把当前循环的索引值保存下来:
var leds = $(".led"); for (var i = 0; i < leds.length; i++) { // 用IIFE把当前i的值传递给index (function(index) { setTimeout(function () { $(leds[index]).css('opacity', '1'); }, 1000 * (index + 1)); })(i); }
方案3:用jQuery的each方法(更简洁)
直接用jQuery的遍历方法,天然解决作用域问题,代码更清爽:
$(".led").each(function(index) { setTimeout(() => { $(this).css('opacity', '1'); }, 1000 * (index + 1)); });
另外,原代码里的alert()可以去掉哦,不然会连续弹出三次,影响交互体验~
内容的提问来源于stack exchange,提问作者Origin
相关产品推荐
相关产品推荐

