开发者问题收集

我不知道如何修复这个错误:未捕获的类型错误:无法读取未定义的属性“classList”

2021-03-07
103

我不太清楚我在操作每个表单字段的 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>
2个回答

您可能想尝试一下

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

您的 querySelector 返回一个 nodeList,但这个它返回一个数组。因此您可以使用它们的索引来选择它们。

İlker
2021-03-07

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

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

该问题与在节点列表末尾禁用下一个按钮的逻辑有关。...您需要将该逻辑移至 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>
gavgrif
2021-03-07