JS实现项目图片随机不重复展示功能后网站无响应问题求助
问题原因
- 死循环触发:每次定时器回调执行时,你都将
randomproject初始化为0,随后直接把oldproject赋值为0,还错误地释放了索引为0的图片占用。当12张图里有6张被展示框占用、且索引0恰好也被其他框占用时,你的while循环要求选中的图片既不能是被占用的、也不能等于0,此时没有符合条件的索引,循环永远无法退出,卡死JS主线程导致页面无响应。 - 旧图释放逻辑错误:你没有记录当前展示框正在使用的图片索引,每次都错误释放索引0的占用,导致索引0的图片会被重复分配,同时当前展示框之前用的图片永远不会被标记为可用,可用的图片会越来越少,最终必然触发死循环。
修复方案
我们改为先过滤出所有当前未被占用的图片列表,再从中随机选取,同时每个展示框单独记录自己当前使用的图片索引,换图时先释放自身旧图的占用:
首先是你原本的HTML结构无需调整:
<div class="project-viewer"> <div id="project1"></div> <div id="project2"></div> <div id="project3"></div> <div id="project4"></div> <div id="project5"></div> <div id="project6"></div> </div>
修复后的JS代码如下:
/*projects grid*/ const projects = [ 'images/project0.png', 'images/project1.jpg', 'images/project2.jpg', 'images/project3.jpg', 'images/project4.png', 'images/project5.png', 'images/project6.png', 'images/project7.png', 'images/project8.png', 'images/project9.jpg', 'images/project10.jpg', 'images/project11.jpg' ]; // 记录每张图片是否被占用 const projectsCheck = new Array(projects.length).fill(false); // 批量获取展示框元素,无需逐个声明 const projectEls = Array.from({length:6}, (_,i) => document.getElementById(`project${i+1}`)); // 6个展示框的换图间隔配置,可按需调整 const intervals = [11000,9000,12000,10000,8000,13000]; function shuffle(projectEl, ms) { 'use strict'; // 记录当前展示框正在使用的图片索引,初始为-1表示未选过图 let currentProjectIndex = -1; setInterval(() => { // 先释放当前展示框占用的旧图 if(currentProjectIndex !== -1) { projectsCheck[currentProjectIndex] = false; } // 过滤出所有未被占用的图片索引 const availableIndexes = projectsCheck.map((used, idx) => used ? null : idx).filter(v => v !== null); // 从可用索引中随机选取 const randomIdx = Math.floor(Math.random() * availableIndexes.length); const selectedIndex = availableIndexes[randomIdx]; // 标记选中的图片为已占用 projectsCheck[selectedIndex] = true; // 更新当前展示框的记录和背景图 currentProjectIndex = selectedIndex; projectEl.style.backgroundImage = `url(${projects[selectedIndex]})`; }, ms); } // 批量初始化所有展示框 projectEls.forEach((el, idx) => shuffle(el, intervals[idx]));
逻辑说明
- 去掉了容易触发死循环的while随机逻辑,直接过滤可用列表再选取,100%不会出现循环卡死问题
- 每个展示框单独记录自身使用的图片索引,换图时正确释放旧图占用,不会出现可用图片越来越少的问题
- 12张图对应6个展示框,永远会有至少6个可用索引,完全满足同一张图片不会被多个展示框同时展示的需求
内容的提问来源于stack exchange,提问作者Ahmed Gouda
相关产品推荐
相关产品推荐

