Nuxt.js图片画廊slideIndex变量未赋值引发TypeError问题求助
图片画廊slideIndex undefined问题修复
问题描述
使用Nuxt.js开发JavaScript图片画廊时,点击缩略图为slideIndex赋值后,控制台显示该变量仍为undefined,导致调用plusSlides时slideIndex变为NaN,执行slides[slideIndex-1].style.display触发TypeError,无法正常切换图片。
问题根源
- 变量作用域冲突:
window.addEventListener('load')内部声明了局部的let slideIndex,与外部全局的slideIndex是两个独立变量,内部赋值不会影响全局变量,导致全局slideIndex始终未初始化。 - DOM选择器遗漏:
document.querySelectorAll(".photo-fullscreen")仅能选中第二张全屏图片,其余两张未添加该类,导致获取的幻灯片集合数量错误。 - 代码冗余且耦合高:手动为每张缩略图绑定重复的点击事件,维护成本高;手动设置每张图片的display属性,逻辑重复。
修复方案
- 统一变量作用域:移除
load事件内部的let slideIndex,直接使用全局变量,确保赋值能被全局函数访问。 - 补全DOM类名:给所有全屏图片添加
photo-fullscreen类,保证选择器能获取全部幻灯片。 - 优化事件绑定:通过循环批量绑定缩略图点击事件,减少重复代码。
- 初始化默认值:给全局
slideIndex设置初始值,避免未赋值时的undefined状态。
修复后的完整代码
JavaScript代码
// 全局初始化slideIndex let slideIndex = 1; window.addEventListener('load', function () { const fullscreenGallery = document.querySelector(".photo-gallery-fullscreen"); const slides = document.querySelectorAll(".photo-fullscreen"); const thumbnails = document.querySelectorAll(".photo-gallery .photo"); // 批量绑定缩略图点击事件 thumbnails.forEach((thumbnail, index) => { thumbnail.onclick = function() { fullscreenGallery.style.display = "block"; // 先隐藏所有幻灯片 slides.forEach(slide => slide.style.display = "none"); // 显示对应幻灯片 slides[index].style.display = "block"; slideIndex = index + 1; }; }); // 关闭弹窗 document.querySelector(".out").onclick = function() { fullscreenGallery.style.display = "none"; slides.forEach(slide => slide.style.display = "none"); slideIndex = 1; }; }); // 切换幻灯片 function plusSlides(n) { showSlides(slideIndex += n); } function showSlides(n) { const slides = document.querySelectorAll(".photo-fullscreen"); const slideCount = slides.length; // 边界处理 if (n > slideCount) { slideIndex = 1; } if (n < 1) { slideIndex = slideCount; } // 隐藏所有幻灯片 slides.forEach(slide => slide.style.display = "none"); // 显示当前幻灯片 slides[slideIndex - 1].style.display = "block"; }
HTML代码(修改部分)
<div class="slide-container"> <!-- 给所有img添加photo-fullscreen类 --> <img src="https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1820&q=80" class="photo-fullscreen" /> <img src="https://images.unsplash.com/photo-1575052814086-f385e2e2ad1b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80" class="photo-fullscreen" /> <img src="https://images.unsplash.com/photo-1524863479829-916d8e77f114?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2670&q=80" class="photo-fullscreen" /> </div>
SCSS代码(无需修改)
// Photo Gallery .photo-gallery-section { margin: 50px 0; .photo-gallery { width: 80%; height: 250px; margin: auto; display: grid; grid-template-rows: 250px; grid-template-columns: repeat(3, 250px); justify-content: space-between; gap: 10px; .photo:hover { cursor: pointer; } .photo:nth-child(1) { background: url(https://images.unsplash.com/photo-1544367567-0f2fcb009e0b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1820&q=80) center center / cover; } .photo:nth-child(2) { background: url(https://images.unsplash.com/photo-1575052814086-f385e2e2ad1b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80) center center / cover; } .photo:nth-child(3) { background: url(https://images.unsplash.com/photo-1524863479829-916d8e77f114?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2670&q=80) center center / cover; } } .photo-gallery-fullscreen { display: none; height: 100vh; width: 100vw; background: rgba(0, 0, 0, 0.4); position: fixed; top: 0; left: 0; z-index: 1; .slide-container { width: fit-content; margin: calc(50vh - 225px) auto; } .slide-container img { height: 450px; z-index: 3; display: none; } .prev, .next { cursor: pointer; color: #333; font-weight: bold; font-size: 40px; z-index: 3; position: absolute; } .prev { margin: calc(50vh - 21px) 0; margin-left: 15vw; left: 0; } .next { margin: calc(50vh - 21px) 0; margin-right: 15vw; right: 0; } .out { position: absolute; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 2; } } }
内容的提问来源于stack exchange,提问作者MH info
相关产品推荐
相关产品推荐

