JS/jQuery如何间隔1秒依次给嵌套数组对应DOM元素增删class
问题根因
你写的同步for循环会瞬间执行完所有逻辑,哪怕在循环里加定时器,所有定时任务也会几乎同时注册,到点一起触发,所以会出现所有元素同时加上up类的情况,根本做不到按组间隔1秒切换的效果。
实现方案
两种写法逻辑完全一致:按数组索引逐组处理,每次处理完当前组就等1秒,处理下一组前先移除上一组元素的up类,再给当前组元素加类。
写法1:async/await(逻辑最直观,推荐)
先封装一个简单的延迟函数,再用异步循环按顺序执行即可:
const sequencing = [["01-01", "02-01", "03-01"],["01-02", "02-02", "03-02"],["01-03", "02-03", "03-03"],["01-04", "02-04", "03-04"]]; // 延迟工具函数 const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); async function playSequence() { for (let i = 0; i < sequencing.length; i++) { // 移除上一组的up类 if (i > 0) { sequencing[i-1].forEach(id => $(`#${id}`).removeClass('up')); } // 给当前组所有元素加up类 sequencing[i].forEach(id => $(`#${id}`).addClass('up')); // 等待1秒再进入下一轮 await wait(1000); } } // 启动执行 playSequence();
写法2:递归步进(兼容无async/await的老环境)
不用Promise也能实现,靠递归+setTimeout按索引逐组调用就行:
const sequencing = [["01-01", "02-01", "03-01"],["01-02", "02-02", "03-02"],["01-03", "02-03", "03-03"],["01-04", "02-04", "03-04"]]; function runStep(currentIndex) { // 所有组跑完就终止 if (currentIndex >= sequencing.length) return; // 清掉上一组的类 if (currentIndex > 0) { sequencing[currentIndex - 1].forEach(id => $(`#${id}`).removeClass('up')); } // 给当前组加类 sequencing[currentIndex].forEach(id => $(`#${id}`).addClass('up')); // 1秒后跑下一组 setTimeout(() => runStep(currentIndex + 1), 1000); } // 从第一组(索引0)开始跑 runStep(0);
扩展说明
- 如果需要无限循环播放,只需要在判断到
currentIndex到数组末尾的时候,把索引重置为0再调用执行逻辑即可 - 不要尝试在同步for循环里直接写
setTimeout加类,这种写法所有定时器会同时计时,1秒后所有类会一起加上,完全达不到间隔效果 - 如果需要中途停止序列,第一种写法可以加个中断标记,第二种写法可以存下setTimeout的id调用
clearTimeout终止
内容的提问来源于stack exchange,提问作者Dela Torre
相关产品推荐
相关产品推荐

