JS使用for循环实现图片画廊弹窗时报getAttribute of undefined错误如何解决
错误根因
该报错与图片加载逻辑无关,由两处语法问题导致:
- 循环变量使用
var声明存在作用域缺陷:var无块级作用域,所有点击事件回调共享同一个i变量,循环执行结束后i的值等于smallImg.length(当前场景下为10),触发点击时smallImg[i]超出数组索引范围,值为undefined,调用getAttribute自然抛出错误。 - 变量引用错误:代码中
value.src的value未提前声明,实际要操作的全图元素是预先定义的fullImg,属于变量名书写错误。
修复方案
方案1:替换var为let(改动最小)
let具备块级作用域,每次循环会生成独立的i变量,点击回调可拿到对应索引的正确值:
const fullImg = document.querySelector(".full-img"); const smallImg = document.querySelectorAll(".gallery img"); const modal = document.querySelector(".modal"); // 仅将var改为let即可 for(let i = 0; i < smallImg.length; i++) { smallImg[i].addEventListener("click", function(){ modal.classList.add("open"); fullImg.classList.add("open"); const originalQuality = smallImg[i].getAttribute('alt'); // 将value替换为正确的全图元素变量名 fullImg.src = `img/full/${originalQuality}.jpg` }) }
方案2:通过事件对象获取点击元素(稳定性更高)
直接从点击事件的target属性取当前触发事件的缩略图,完全规避索引关联问题:
const fullImg = document.querySelector(".full-img"); const smallImg = document.querySelectorAll(".gallery img"); const modal = document.querySelector(".modal"); for(var i = 0; i < smallImg.length; i++) { smallImg[i].addEventListener("click", function(e){ modal.classList.add("open"); fullImg.classList.add("open"); // 直接从事件对象取点击的图片元素 const originalQuality = e.target.getAttribute('alt'); fullImg.src = `img/full/${originalQuality}.jpg` }) }
方案3:用forEach遍历绑定事件(写法更简洁)
querySelectorAll返回的节点列表原生支持forEach遍历,可直接拿到每个元素的引用,无需手动处理索引:
const fullImg = document.querySelector(".full-img"); const smallImg = document.querySelectorAll(".gallery img"); const modal = document.querySelector(".modal"); smallImg.forEach(img => { img.addEventListener("click", () => { modal.classList.add("open"); fullImg.classList.add("open"); const originalQuality = img.getAttribute('alt'); fullImg.src = `img/full/${originalQuality}.jpg` }) })
内容的提问来源于stack exchange,提问作者alwaysLearning
相关产品推荐
相关产品推荐

