You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让handleDelete函数正确获取并移除Library数组指定元素?

问题修复方案

核心问题拆解

你的代码存在几个关键问题导致删除功能失效:

  1. 索引获取方式不稳定:依赖e.path[1].attributes[1]获取索引,DOM结构变化会直接导致获取失败,逻辑不严谨。
  2. 数组操作错误:使用find方法只能匹配元素,无法生成移除目标项后的新数组。
  3. 索引与数组脱节:全局count变量维护的data-target值,会随着重复渲染与数组实际索引不匹配。
  4. 重复渲染问题:viewBookList每次调用未清空现有卡片,导致DOM重复添加元素。
  5. 构造函数错误:Book构造函数返回bookInfo()(无返回值),导致实例化的Book对象为undefined,无法正确存入数组。
  6. 错误清空数组:createBook里的myLibrary = []会清空所有已有书籍,完全不符合需求。

分步修复代码

1. 修正Book构造函数

移除构造函数中的return this.bookInfo();,避免覆盖构造函数默认返回的实例对象:

function Book(title, author, pages, read) {
  this.title = title;
  this.author = author;
  this.pages = Number(pages);
  this.read = Boolean(read);

  // Methods
  this.bookInfo = function () {
    const wasRead = this.read === true ? 'read' : 'not read';
    console.log(
      `${this.title} written by ${this.author}, ${this.pages} pages in length was ${wasRead}.`,
    );
  };

  // 仅调用方法,不返回,保留构造函数默认返回的this
  this.bookInfo();
}

2. 移除createBook中的错误数组清空

删除createBook里的myLibrary = [],同时修正checkbox状态获取逻辑:

function createBook(e) {
  e.preventDefault();
  // 移除错误的数组清空:myLibrary = [];

  let title = document.querySelector('#title').value;
  let author = document.querySelector('#author').value;
  let pages = document.querySelector('#pages').value;
  let read = document.querySelector('#read').checked; // checkbox用checked获取布尔状态

  const newBook = new Book(title, author, pages, read); 
  addBookToLibrary(newBook);
  clearForm();
  viewBookList(myLibrary);
}

3. 修正索引绑定逻辑

删除全局count变量,在viewBookList中直接用数组当前索引设置data-target,同时每次渲染前清空现有卡片:

// 删除全局count变量:let count = myLibrary.length - 3;

function createCard() {
  let bookCard = document.createElement('div');
  bookCard.classList.add('card');
  // 移除这里的data-target设置,放到viewBookList里
  return bookCard;
}

function viewBookList(list) {
  const bookDiv = document.querySelector('.book-list');
  // 每次渲染前清空现有卡片,避免重复
  bookDiv.innerHTML = '';

  // 用entries()遍历,同时获取索引和元素
  for (let [index, bookDetails] of list.entries()) {
    let renderCard = createCard();
    const deleteButton = removeBookBtn();
    // 直接绑定当前数组索引为data-target
    renderCard.setAttribute('data-target', index);

    deleteButton.addEventListener('click', handleDelete);
    setCardStyle(renderCard, bookDetails);

    renderCard.appendChild(deleteButton);
    bookDiv.appendChild(renderCard);
  }

  return bookDiv;
}

4. 重写handleDelete函数

稳定获取目标索引,正确修改数组并重新渲染:

function handleDelete(e) {
  // 找到当前按钮所在的卡片元素
  const card = e.currentTarget.closest('.card');
  if (!card) return;

  // 获取并转换索引为数字
  const bookIndex = parseInt(card.dataset.target);
  if (isNaN(bookIndex)) return;

  // 用filter生成新数组(纯函数方式,推荐)
  myLibrary = myLibrary.filter((_, index) => index !== bookIndex);

  // 或用splice修改原数组:myLibrary.splice(bookIndex, 1);

  // 重新渲染列表
  viewBookList(myLibrary);
}

5. 修正HTML标签错误

原代码中<section class="modal open">的闭合标签错误,修正为:

<section class="modal open">
  <div class="modal-container">
    <!-- 模态框内容 -->
  </div>
</section>
<section class="card-section">
  <button class="btn open-modal" id="open-modal">Add Book</button> 
  <div class="book-list">
    <!-- 卡片容器 -->
  </div>
</section>

内容的提问来源于stack exchange,提问作者JackJack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:55:18