6槽图片画廊定时随机替换非展示图片逻辑求助
问题
需要实现图片画廊逻辑:随机选择索引替换图片,直至所有未展示图片用完后重启。具体需求:
- 拥有含6个图片槽位的画廊,图片对象结构如下:
{ "src" : { "1x" : "/clients/Logo-1.png", "2x" : "/clients/Logo-1@2x.png", "3x" : "/clients/tLogo-1@3x.png" }, "alt" : "xyz" }
- 先从图片数组中随机选6张展示在槽位中;
- 每5秒随机选一个槽位,替换为当前未在画廊中展示的新图片;
- 所有未展示图片用完后,继续循环执行替换逻辑,确保替换的图片不在当前画廊的6张中。
以下是尝试的实现代码:
let randomList = this.shuffleArray(this.LogosListObj); let FirstSixImg = randomList.slice(0, 6); let LeftAllImg = randomList.slice(6 + 1); let RandomIndex = this.randomNoRepeats([0,1,2,3,4,5]) let RandomSecoundImg = this.randomNoRepeats(Array.apply(null, new Array(LeftAllImg.length)).map(function(el, i) {return i})) let RandomFirstImg = this.randomNoRepeats(Array.apply(null, new Array(FirstSixImg.length)).map(function(el, i) {return i})) this.ImageToShowList = [...FirstSixImg]; let checkArr = []; let checkArr2 = []; let flag = false; let index,secndIndex,thirdIndex; const LogoChange = (arr) =>{ if(!flag) { secndIndex = RandomSecoundImg(); console.log('1st',secndIndex) if(checkArr.indexOf(secndIndex) == -1) { index = RandomIndex(); checkArr.push(secndIndex) ctl.ImageToShowList[index] = {}; ctl.ImageToShowList[index] = LeftAllImg[secndIndex]; Vue.set(ctl.ImageToShowList, index, LeftAllImg[secndIndex]) ctl.PreviousImgObj = {...LeftAllImg[secndIndex]}; } else { flag = true; checkArr = []; } } if(flag) { thirdIndex = RandomFirstImg(); console.log('2nd',thirdIndex) if(checkArr2.indexOf(thirdIndex) == -1) { checkArr2.push(thirdIndex) ctl.ImageToShowList[thirdIndex] = {}; ctl.ImageToShowList[thirdIndex] = FirstSixImg[thirdIndex]; Vue.set(ctl.ImageToShowList, thirdIndex, FirstSixImg[thirdIndex]) ctl.PreviousImgObj = {...FirstSixImg[thirdIndex]}; }else { flag = false; checkArr2 = []; LogoChange(); } } } setInterval(()=>{ LogoChange(); }, 1000);
辅助方法实现:
// randomNoRepeats方法 randomNoRepeats : (array) => { var copy = array.slice(0); return function() { if (copy.length < 1) { copy = array.slice(0); } var index = Math.floor(Math.random() * copy.length); var item = copy[index]; copy.splice(index, 1); return item; }; } // shuffleArray方法 shuffleArray : (array) => { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; },
this.ImageToShowList用于HTML渲染展示,需要修正逻辑或优化。
修正与优化方案
1. 修复基础错误
LeftAllImg = randomList.slice(6 + 1)修改为randomList.slice(6),slice(6)会从索引6开始截取到数组末尾,原写法会漏掉第7张图片;setInterval的时间参数从1000改为5000,符合需求的每5秒替换一次;- 代码中未定义的
ctl替换为this,若使用Vue组件,建议提前保存this为self避免箭头函数指向问题。
2. 重构核心逻辑,简化状态管理
原逻辑用flag和两个校验数组切换状态易混乱,可维护两个核心集合:
- 当前展示的图片列表
currentGallery(对应ImageToShowList); - 待替换图片池
pool,初始为除初始6张外的所有图片,当pool为空时,重新从所有不在当前画廊的图片中洗牌生成新池。
优化后核心代码:
const self = this; const allLogos = [...this.LogosListObj]; // 复制原数组避免污染 // 洗牌后取前6张作为初始画廊 const shuffled = this.shuffleArray(allLogos); self.ImageToShowList = shuffled.slice(0, 6); // 初始化待替换池 let pool = shuffled.slice(6); // 生成不重复的槽位索引生成器 const getRandomSlot = this.randomNoRepeats([0,1,2,3,4,5]); const replaceLogo = () => { // 池为空时,重新生成:筛选出当前画廊未包含的图片并洗牌 if (pool.length === 0) { const currentSrcs = self.ImageToShowList.map(img => img.src['1x']); // 用src.1x作为图片唯一标识 pool = self.shuffleArray(allLogos.filter(img => !currentSrcs.includes(img.src['1x']))); } // 随机取槽位和待替换图片 const slotIndex = getRandomSlot(); const newLogo = pool.pop(); // 从池末尾取,效率更高 // Vue响应式更新数组 Vue.set(self.ImageToShowList, slotIndex, newLogo); }; // 启动定时任务并保存实例,用于组件销毁时清理 self.logoInterval = setInterval(replaceLogo, 5000);
3. 优化辅助方法
shuffleArray增加原数组复制,避免修改原数据,并用解构赋值简化交换逻辑:
shuffleArray: (array) => { const newArray = [...array]; for (let i = newArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; } return newArray; }
4. 内存泄漏防护
在Vue组件销毁时清除定时器:
beforeUnmount() { clearInterval(this.logoInterval); }
内容的提问来源于stack exchange,提问作者Anil
相关产品推荐
相关产品推荐

