我不知道如何解决这个错误:Uncaught TypeError: Cannot read property 'classList' of undefined

问题描述

我不确定在为每个表单字段操作 DOM 元素时我做错了什么。我正在创建一个图像轮播。我正在使用上一个和下一个按钮。要转到数组中的下一个元素,我使用 class.List 属性添加删除 HTML 中类的“活动”部分。我认为这是不起作用的原因,但我不知道如何解决

这是 JavaScript

const prevBtn = document.querySelector(".prev");
const nextBtn = document.querySelector(".next");
const galleryImgs = document.querySelectorAll(".gallery-img");
let currentlySelected = 0;

nextBtn.addEventListener("click",next);

function next() {
  
  galleryImgs[currentlySelected].classList.remove("active");
  currentlySelected++; //currentlySelected=currentlySelected+1
  galleryImgs[currentlySelected].classList.add("active");
  prevBtn.disabled = false; 
}


if (galleryImgs.length === currentlySelected + 1) {
  nextBtn.disabled = true;
}

和 HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <Meta charset="UTF-8" />
    <Meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <Meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>gallery</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <div class="image-gallery">
      <img src="./images/1.jpg" alt="Luna" class="gallery-img active" />
      <img src="./images/2.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/3.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/4.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/5.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/6.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/7.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/8.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/9.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/10.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/11.jpg" alt="Luna" class="gallery-img" />
      <img src="./images/12.jpg" alt="Luna" class="gallery-img" />
    </div>
    <div class="btns">
      <button disabled="" class="btn prev">Prev</button>
      <button class="btn next">Next</button>
    </div>
    <script src="./gallery.js"></script>
  </body>
</html>

解决方法

你可能想试试这个

const galleryImgs = [...document.querySelectorAll(".gallery-img")];

您的 querySelector 返回一个 nodeList,但它返回一个数组。所以你可以用它们的索引选择它们。

,

问题是关于更新索引,而不是关于数组与节点列表 - document.querySelectorAll nodeLists 可以通过索引访问

问题是当您前进到列表末尾时下一个按钮没有被禁用 - 当您已经在最后一个项目上然后单击下一步时有效 - 没有项目可以获取类列表 -因此它是未定义的。

该问题与在节点列表末尾时禁用下一个按钮的逻辑有关。 ...您需要将该逻辑移至 next() 函数,以便在您选择最后一项时禁用它。

以下在活动项目周围放置了一个红色轮廓,您可以看到单击下一个按钮的行为与已执行 - 每次单击都会增加计数并将活动类添加到下一个项目。我换了毛茸茸的小猫图片,因为我无法访问您正在使用的图片,并且不喜欢带有替代文字外观的损坏图片。

我已经扩展了您正在做的事情 - 并在上一个按钮上添加了一个点击处理程序和功能,类似地 - 如果第一项已被重新选择,则在那里有逻辑以禁用前一个按钮,

我可能会以不同的方式来做这件事,并有一个函数来处理向上或向下的句柄 - 但是为 indiv 操作使用 indiv 函数是很好的。

无论哪种方式-您使用的节点列表方法都很好-没有扩展运算符更改-一旦到达数组的末尾就无法解决问题-或返回到数组的开头...:)>

const prevBtn = document.querySelector(".prev");
const nextBtn = document.querySelector(".next");
const galleryImgs = document.querySelectorAll(".gallery-img");
let currentlySelected = 0;

nextBtn.addEventListener("click",next);
prevBtn.addEventListener("click",prev);

function next() {
  galleryImgs[currentlySelected].classList.remove("active");
  currentlySelected++; //currentlySelected=currentlySelected+1
  galleryImgs[currentlySelected].classList.add("active");
  prevBtn.disabled = false; 
  
  if (galleryImgs.length === currentlySelected + 1) {
  nextBtn.disabled = true;
  }
}

function prev() {
  galleryImgs[currentlySelected].classList.remove("active");
  currentlySelected--; //currentlySelected=currentlySelected+1
  galleryImgs[currentlySelected].classList.add("active");
  nextBtn.disabled = false; 
  
  if (currentlySelected == 0) {
   prevBtn.disabled = true;
  }
}
.active {
outline: solid 1px red;
}

img {
 height: 50px;
 width: 50px;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Gallery</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <div class="image-gallery">
      <img src="https://cf.ltkcdn.net/cats/images/slide/188392-850x668-Cute-fuzzy-7.jpg" alt="Luna" class="gallery-img active" />
      <img src="https://c8.alamy.com/comp/W7TNYR/fluffy-kitten-8-weeks-among-pink-flowers-W7TNYR.jpg" alt="Luna" class="gallery-img" />
      <img src="https://cf.ltkcdn.net/cats/images/slide/188392-850x668-Cute-fuzzy-7.jpg" alt="Luna" class="gallery-img" />
      <img src="https://c8.alamy.com/comp/W7TNYR/fluffy-kitten-8-weeks-among-pink-flowers-W7TNYR.jpg" alt="Luna" class="gallery-img" />
      <img src="https://cf.ltkcdn.net/cats/images/slide/188392-850x668-Cute-fuzzy-7.jpg" alt="Luna" class="gallery-img" />
      <img src="https://c8.alamy.com/comp/W7TNYR/fluffy-kitten-8-weeks-among-pink-flowers-W7TNYR.jpg" alt="Luna" class="gallery-img" />
      <img src="https://cf.ltkcdn.net/cats/images/slide/188392-850x668-Cute-fuzzy-7.jpg" alt="Luna" class="gallery-img" />
      <img src="https://c8.alamy.com/comp/W7TNYR/fluffy-kitten-8-weeks-among-pink-flowers-W7TNYR.jpg" alt="Luna" class="gallery-img" />
      <img src="https://cf.ltkcdn.net/cats/images/slide/188392-850x668-Cute-fuzzy-7.jpg" alt="Luna" class="gallery-img" />
      <img src="https://c8.alamy.com/comp/W7TNYR/fluffy-kitten-8-weeks-among-pink-flowers-W7TNYR.jpg" alt="Luna" class="gallery-img" />
      <img src="https://cf.ltkcdn.net/cats/images/slide/188392-850x668-Cute-fuzzy-7.jpg" alt="Luna" class="gallery-img" />
      <img src="https://c8.alamy.com/comp/W7TNYR/fluffy-kitten-8-weeks-among-pink-flowers-W7TNYR.jpg" alt="Luna" class="gallery-img" />
    </div>
    <div class="btns">
      <button disabled="" class="btn prev">Prev</button>
      <button class="btn next">Next</button>
    </div>
    <script src="./gallery.js"></script>
  </body>
</html>