原生JS图片画廊点击缩略图始终切换为最后一张图问题
问题描述
使用原生JavaScript开发简易图片画廊组件时,已完成缩略图点击触发主图切换的基础逻辑,但存在交互异常:点击任意缩略图,主展示区都会固定切换为缩略图列表最后一张(第4张)的图片,无法正常显示当前点击的目标图片。
实现逻辑中通过DOM的dataset属性存储每个缩略图对应的原图URL,供切换逻辑读取,初步定位问题出在缩略图遍历的for循环逻辑上。
原有问题代码
HTML部分
<section id="showcase"> <div id="display-area"> <img src="https://source.unsplash.com/wtGWZbiDhGc" id="display-image" alt="unpicked oranges on a tree" /> </div> <ul id="thumbnails"> <li class="thumbnail"> <img src="https://source.unsplash.com/wtGWZbiDhGc" alt="" class="thumb-img" data-thumbsrc="https://source.unsplash.com/wtGWZbiDhGc"/> </li> <li class="thumbnail"> <img src="https://source.unsplash.com/gKR4mOceulU" alt="" class="thumb-img" data-thumbsrc="https://source.unsplash.com/gKR4mOceulU"/> </li> <li class="thumbnail"> <img src="https://source.unsplash.com/Jz4QMhLvGgw" alt="" class="thumb-img" data-thumbsrc="https://source.unsplash.com/Jz4QMhLvGgw"/> </li> <li class="thumbnail"> <img src="https://source.unsplash.com/I7dpBg-Z5Cc" alt="" class="thumb-img" data-thumbsrc="https://source.unsplash.com/I7dpBg-Z5Cc"/> </li> </ul> </section>
JS部分
const thumbnail = document.querySelectorAll('.thumbnail'); thumbnail.forEach(function(thumb){ thumb.addEventListener("click", changeImage); }); // elements const displayArea = document.querySelector('#display-area'); let displaysrc = document.querySelector('#display-image'); // the display image's img tag let thumbImg = document.querySelectorAll('.thumb-img'); // all img elements w/ thumb-img class function changeImage(){ // check current value of display image src console.log("current display src " + displaysrc.src); for (var i = 0; i < thumbImg.length; i++){ let thumbsrc = thumbImg[i].dataset.thumbsrc; displaysrc.setAttribute('src', thumbsrc); } // check new value of display image src console.log("new display src " + displaysrc.src); };
问题根因
初步判断完全准确:点击事件触发后,changeImage函数会遍历所有缩略图节点,循环过程中依次将主图的src属性赋值为当前遍历到的缩略图资源地址,循环结束后主图src会被最后一次赋值(即最后一张缩略图的地址)覆盖,因此无论点击哪个缩略图,最终都只会显示最后一张图片。
本质问题是现有逻辑没有获取当前被点击的那一个缩略图的对应地址,反而无差别遍历了所有缩略图重复赋值。
修复方案
删除点击事件中无意义的全量缩略图遍历逻辑,通过事件对象拿到当前触发点击的目标元素,读取其存储的原图地址后,仅做一次主图地址赋值即可。
修复后的JS代码如下:
// 统一在逻辑最前获取需要的DOM元素 const thumbnailList = document.querySelectorAll('.thumbnail'); const mainDisplayImg = document.querySelector('#display-image'); // 给每个缩略图绑定点击事件 thumbnailList.forEach(function(thumb){ thumb.addEventListener("click", changeImage); }); function changeImage(e){ // 拿到当前点击的缩略图容器内的图片元素 const clickedThumb = e.currentTarget.querySelector('.thumb-img'); // 读取预存的原图地址 const targetImgSrc = clickedThumb.dataset.thumbsrc; // 给主展示图赋值 mainDisplayImg.src = targetImgSrc; console.log("切换后主图地址:" + mainDisplayImg.src); }
可选优化
如果不想每次点击都查找子元素,可以直接把点击事件绑定在 class 为thumb-img的图片元素上,事件触发时直接读取当前元素的dataset.thumbsrc即可,代码更简洁:
const thumbImgList = document.querySelectorAll('.thumb-img'); const mainDisplayImg = document.querySelector('#display-image'); thumbImgList.forEach(function(thumbImg){ thumbImg.addEventListener("click", function(e){ mainDisplayImg.src = e.currentTarget.dataset.thumbsrc; }); });
内容的提问来源于stack exchange,提问作者Danielle
相关产品推荐
相关产品推荐

