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

如何实现点击删除对应的图书元素?

问题描述

我有一个带输入框的表单,输入值会以对象形式存储在数组中,同时这些值会在浏览器中展示。现在希望用户能删除点击的展示元素(即对应的对象),但当前设置的deleteBook函数删除行为混乱,请问需要修改哪些内容才能实现点击删除对应元素?

HTML代码

<div class="readContainer">
    <label for="radio">已读?</label>
    <div class="checkReadContainer">
        <input type="checkbox" id="read" name="read" value="yes">
    </div>
</div>

<button id="btn" onclick="createBook();">提交</button>
</div>

<div class="displayMessageContainer">
    <p id="displayBook">📚 最多存储10本书 📚</p>
    <p id="infoTestVersion"> 或 <a href="#" id="signUp"> 注册 </a>免费试用,即可获得30天无限图书存储空间*</p>
</div>

<div class="Display">
    <p class="display"> </p>
</div>

<footer>
    <div class="footerContainer">
        <div class="madeBy">
            <h1> made by anitakath <i class="fa-brands fa-github"></i> </h1>
        </div>
    </div>
</footer>

JavaScript代码

const labels = document.querySelectorAll("label");
const inputs = document.querySelectorAll("input");
const title = document.getElementById("title");
const author = document.getElementById("author");
const pages = document.getElementById("pages");
const button = document.getElementById("btn");
const displayArea = document.querySelector(".display");

let myLibrary = [];

function Book(title, author, pages) {
  this.title = title.value;
  this.author = author.value;
  this.pages = pages.value;
}

Book.prototype.introduction = function () {
  return `${this.title} by ${this.author}, `;
};

Book.prototype.introductionII = function () {
  return `with ${this.pages} pages`;
};

let errorMessage = document.getElementById("displayBook");

function createBook() {
  if (title.value && author.value && pages.value) {

    let bookX = new Book(title, author, pages);
 
    let card = document.createElement("div");
    card.classList.add("cardStyle");
    displayArea.appendChild(card);

    let cardSectionLeft = document.createElement("div");
    let cardSectionRight = document.createElement("div");
    cardSectionLeft.classList.add("cardLeft");
    cardSectionRight.classList.add("cardRight");

    card.appendChild(cardSectionLeft);
    card.appendChild(cardSectionRight);

    let deleteButton = document.createElement("div");
    let deleteContent = document.createElement("p");
    deleteContent.innerText = "X";
    deleteButton.classList.add("deleteButton");
    deleteButton.appendChild(deleteContent);
    cardSectionRight.appendChild(deleteButton);

    deleteButton.setAttribute("onclick", "deleteBook();");

    let cardIntro = document.createElement("h3");
    let cardOutro = document.createElement("p");
    cardIntro.innerText = bookX.introduction();
    cardOutro.innerText = bookX.introductionII();
    cardSectionLeft.appendChild(cardIntro);
    cardSectionRight.appendChild(cardOutro);

    bookArray = [title.value, author.value, pages.value];

    const bookArrayToObject = Object.assign({}, bookArray);
    console.log(bookArrayToObject);

    myLibrary.push(bookArrayToObject);
    console.log(myLibrary);
    console.log(myLibrary[0]);
    console.log(myLibrary[1]);
    console.log(myLibrary[2]);

    const radio = document.getElementById("read");
    if (radio.checked) {
      card.classList.add("read");
    } else if (!radio.checked) {
      card.classList.add("notread");
    }

    errorMessage.innerText = `已保存: ${this.title.value} by ${this.author.value}, with ${this.pages.value} pages`;
    errorMessage.style.color = "green";
  } else if (!title.value || !author.value || !pages.value) {
    errorMessage.innerText =
      "请确保所有输入框都已填写";
    errorMessage.style.color = "red";
  }
}

function deleteBook() {
  for (let i = 0; i < myLibrary.length; i++) {
    console.log(myLibrary.splice(i, 1));
  }
}   
修改方案

1. 给图书对象添加唯一标识

当前存储的图书对象没有唯一ID,无法精准匹配DOM元素和数组元素。修改Book构造函数,给每个图书生成唯一ID:

let bookIdCounter = 0;
function Book(title, author, pages) {
  this.id = ++bookIdCounter; // 自增唯一ID
  this.title = title.value;
  this.author = author.value;
  this.pages = pages.value;
}

同时直接将图书实例推入数组,无需转数组再转对象:

// 替换原bookArray和bookArrayToObject相关代码
myLibrary.push(bookX);

2. 绑定删除按钮时传递对应图书ID

创建删除按钮时,将当前图书的ID传入删除函数,并把ID存在DOM卡片的自定义属性中:

// 替换deleteButton.setAttribute那一行代码
card.dataset.bookId = bookX.id; // 给卡片标记对应图书ID
deleteButton.onclick = function() {
  deleteBook(bookX.id);
};

3. 重写deleteBook函数

原函数会循环删除整个数组,改成根据ID精准删除对应元素并移除DOM卡片:

function deleteBook(bookId) {
  // 删除数组中对应ID的图书
  const targetIndex = myLibrary.findIndex(book => book.id === bookId);
  if (targetIndex !== -1) {
    myLibrary.splice(targetIndex, 1);
  }
  // 删除页面上对应的卡片
  const targetCard = document.querySelector(`[data-book-id="${bookId}"]`);
  if (targetCard) {
    targetCard.remove();
  }
  // 更新提示信息
  errorMessage.innerText = myLibrary.length > 0 
    ? `剩余${myLibrary.length}本图书` 
    : "📚 最多存储10本书 📚";
  errorMessage.style.color = "black";
}

4. 修正提示信息的错误

原createBook函数中提示信息的this.title.value指向错误,改成使用bookX的属性:

errorMessage.innerText = `已保存: ${bookX.title} by ${bookX.author}, with ${bookX.pages} pages`;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:10:26