You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Odin项目Library功能:点击删除按钮时数组元素删除错误且新增书籍异常问题求助

Odin项目Library功能:点击删除按钮时数组元素删除错误且新增书籍异常问题求助

嘿,我仔细看了你的代码,发现了几个导致问题的关键点,咱们一步步来解决:

一、删除按钮删错数组元素的原因及解决办法

你现在的核心问题是:删除某本书后,剩下书籍的删除按钮绑定的还是原数组的索引,但数组已经因为删除元素发生了长度变化,索引对应关系被打乱,所以会出现删错元素的情况。

举个例子:初始数组是[A,B,C],每个删除按钮对应索引0、1、2。删掉A后数组变成[B,C],但B的删除按钮还是绑定的索引1,这时候点击B的删除按钮,会删掉数组里索引1的元素也就是C,而不是B。

解决方法:把渲染书籍列表的逻辑抽成单独函数,每次修改数组后都重新渲染

这样每次删除或新增书籍后,所有卡片都会重新创建,删除按钮绑定的索引也会是当前数组的正确索引。具体步骤:

  1. 新建一个renderLibrary函数,把原来submit事件里渲染卡片的代码移进去:
function renderLibrary() {
  bookDisplay.textContent = "";
  // 计算全局已读书籍数量
  const totalBooksRead = myLibrary.filter(book => book.read === "READ").length;
  booksReadTracker.textContent = totalBooksRead;
  bookTracker.textContent = myLibrary.length;

  myLibrary.forEach((item, index) => {
    const div = document.createElement("div");
    div.classList.add("book-card");
    div.innerHTML = `
      <button class="remove-book">X</button>
      <p class="title-info">TITLE: ${item.title}</p>
      <p class="author-info">AUTHOR: ${item.author}</p>
      <p class="pages-info">PAGES: ${item.numOfPages}</p>
    `;

    const readButton = document.createElement("button");
    readButton.classList.add("read-button");
    readButton.textContent = item.read;
    div.appendChild(readButton);

    if (item.read === "READ") {
      readButton.style.backgroundColor = "lightgreen";
    } else {
      readButton.style.backgroundColor = "lightcoral";
    };

    bookDisplay.appendChild(div);

    // 阅读状态切换事件
    readButton.addEventListener("click", function() {
      if (item.read === "NOT READ") {
        readButton.style.backgroundColor = "lightgreen";
        item.read = "READ";
      } else {
        readButton.style.backgroundColor = "lightcoral";
        item.read = "NOT READ";
      }
      // 重新渲染更新已读数量
      renderLibrary();
    })

    // 删除书籍事件
    const removeBook = div.querySelector(".remove-book");
    removeBook.addEventListener("click", function() {
      myLibrary.splice(index, 1);
      // 重新渲染更新列表和统计
      renderLibrary();
    })
  })
}
  1. 修改submit事件里的代码,调用这个函数代替原来的循环:
form.addEventListener("submit", function(event) {
  event.preventDefault();

  const title = bookTitleInput.value;
  const author = bookAuthorInput.value;
  const numOfPages = bookNumOfPagesinput.value;
  let read = "NOT READ";

  if (bookReadCheckboxInput.checked) {
    read = "READ";
    bookReadCheckboxInput.checked = false;
  }

  // 直接push新书到数组,去掉多余的原型方法
  const newBook = new Book(title, author, numOfPages, read);
  myLibrary.push(newBook);

  // 清空输入框
  bookTitleInput.value = "";
  bookAuthorInput.value = "";
  bookNumOfPagesinput.value = "";

  // 重新渲染列表
  renderLibrary();
  console.log(myLibrary);
})
  1. 删掉多余的Book.prototype.pushToArray方法和addBookToLibary函数,直接在submit里创建新书并push到数组,这样更简洁不容易出错。

二、新增书籍有时出现两本的原因及解决办法

这个问题大概率是因为表单的submit事件被绑定了多次(比如脚本被重复加载,或者代码执行了两次addEventListener),或者之前的原型方法调用有潜在问题。

解决方法:

  1. 用上面的修改,直接在submit里push新书,去掉多余的原型方法,避免不必要的调用。
  2. 如果还是出现重复提交,可以给addEventListener加上once: true选项,确保事件只触发一次:
form.addEventListener("submit", function(event) {
  // 原来的代码
}, { once: false }); // 或者如果确定只需要绑定一次,设为true

不过更稳妥的是确保你的脚本只加载一次,没有重复引入。

额外优化:修复已读书籍统计的问题

你原来的代码里,booksRead变量是在forEach循环里定义的,每个read按钮的事件只会修改当前书籍对应的变量,导致统计的已读数量不正确。现在在renderLibrary里用myLibrary.filter(book => book.read === "READ").length计算全局已读数量,就能正确显示总数了。

现在把这些修改后,你的删除和新增功能应该就能正常工作啦!

备注:内容来源于stack exchange,提问作者Wrcnow

火山引擎 最新活动