循环遍历数组结合setTimeout切换图片src/rel时仅显示最后元素的问题
解决定时遍历数组切换图片仅显示最后一张的问题
问题根源
- 所有
setTimeout都设了1000ms延迟,三个回调几乎同时触发,最后一次替换会覆盖前两次的结果 - 代码里的
val没声明成局部变量,变成了全局变量,循环结束后val固定是数组最后一个元素,所有回调都用这个值 - 直接用
html()替换元素,既没法做淡入淡出,也不符合“修改现有图片属性”的需求
修复步骤
1. 先搞定定时器延迟和变量作用域
把延迟时间改成i * 1000,让每个回调依次延迟执行;同时用const把val声明成循环迭代内的局部变量:
const arr = ['abc.png', 'def.png', 'ghi.png']; for(let i = 0; i < arr.length; i++) { const val = arr[i]; setTimeout(function() { $("#example").html(`<img src="${val}" rel="${val}" style='width:100%'>`); }, i * 1000); // 每个回调延迟时间递增,实现依次切换 }
2. 改属性而非替换元素,实现淡入淡出
先在页面放好基础的img元素:
<div id="example"> <img src="abc.png" rel="abc.png" style="width:100%; display:none;"> </div>
然后通过修改src和rel切换图片,结合jQuery的淡入淡出方法做平滑过渡:
const arr = ['abc.png', 'def.png', 'ghi.png']; const $img = $("#example img"); // 先显示第一张图 $img.attr({src: arr[0], rel: arr[0]}).fadeIn(); for(let i = 1; i < arr.length; i++) { const val = arr[i]; setTimeout(function() { $img.fadeOut(function() { // 淡出完成后修改属性再淡入 $(this).attr({src: val, rel: val}).fadeIn(); }); }, i * 1000); }
3. 处理嵌套数组的情况
如果是嵌套结构的数组(比如[['abc.png'], ['def.png', 'ghi.png']]),先把数组扁平化再遍历:
// 扁平化任意深度的嵌套数组 const nestedArr = [['abc.png'], ['def.png', 'ghi.png']]; const flatArr = nestedArr.flat(Infinity); const $img = $("#example img"); $img.attr({src: flatArr[0], rel: flatArr[0]}).fadeIn(); for(let i = 1; i < flatArr.length; i++) { const val = flatArr[i]; setTimeout(function() { $img.fadeOut(function() { $(this).attr({src: val, rel: val}).fadeIn(); }); }, i * 1000); }
4. 递归实现循环切换(更可控)
如果需要循环轮播图片,递归方式比定时器堆积更靠谱:
const flatArr = ['abc.png', 'def.png', 'ghi.png']; const $img = $("#example img"); let index = 0; function switchImage() { $img.fadeOut(function() { $(this).attr({src: flatArr[index], rel: flatArr[index]}).fadeIn(); index = (index + 1) % flatArr.length; // 到最后一张后回到第一张 setTimeout(switchImage, 1000); }); } // 初始化第一张图,然后启动轮播 $img.attr({src: flatArr[0], rel: flatArr[0]}).fadeIn(); setTimeout(switchImage, 1000);
内容的提问来源于stack exchange,提问作者gothmog
相关产品推荐
相关产品推荐

