JavaScript:for循环中添加类时设置setTimeout无效的问题排查
解决循环中使用setTimeout为元素逐个添加淡入类的问题
我来帮你搞定这个问题!你遇到的是JavaScript里循环结合setTimeout时很常见的变量作用域陷阱,同时代码里还有个小细节需要调整,咱们一步步来解决:
问题根源
你原来的代码用var i声明循环变量,var是函数级作用域,所有setTimeout的回调函数都会共享同一个i变量。等定时器触发的时候,循环早就跑完了,i的值已经变成了children.length + 1,这时候nth-of-type(" + i + ")根本找不到对应的元素,自然看不到效果。另外,CSS的nth-of-type是从1开始计数的,你原来循环从0开始,nth-of-type(0)是无效的,这也是一个小问题。
解决方案
这里给你三种可行的方法,选你觉得顺手的就行:
方法1:用let声明循环变量(ES6+ 最简单)
let是块级作用域,每次循环都会创建一个独立的i变量,每个定时器拿到的都是当前循环的i值,完美避开作用域问题:
var children = $("#phototitle span"); for (let i = 1; i <= children.length; i++) { setTimeout(() => { $("#phototitle span:nth-of-type(" + i + ")").addClass("flip-in-hor-bottom"); console.log(children[i - 1]); // children是0索引,所以要减1 }, i * 500); // 每个元素延迟递增,比如第一个500ms,第二个1000ms,可自行调整时间 }
方法2:用闭包兼容旧环境
如果需要兼容不支持ES6的旧浏览器,可以用立即执行函数(IIFE)把每个循环的i值保存起来:
var children = $("#phototitle span"); for (var i = 1; i <= children.length; i++) { (function(currentIndex) { setTimeout(function() { $("#phototitle span:nth-of-type(" + currentIndex + ")").addClass("flip-in-hor-bottom"); console.log(children[currentIndex - 1]); }, currentIndex * 500); })(i); }
方法3:用jQuery的each方法(更贴合jQuery风格)
直接用jQuery的遍历方法,能直接拿到每个元素和对应的索引,代码更简洁:
$("#phototitle span").each(function(index) { var $element = $(this); setTimeout(function() { $element.addClass("flip-in-hor-bottom"); console.log($element[0]); }, (index + 1) * 500); // index从0开始,加1让延迟依次递增 });
小提示
你可以调整setTimeout的第二个参数(比如改成300),来控制每个元素淡入的间隔时间,找到最适合的动画节奏。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

