如何实现点击删除对应的图书元素?
问题描述
我有一个带输入框的表单,输入值会以对象形式存储在数组中,同时这些值会在浏览器中展示。现在希望用户能删除点击的展示元素(即对应的对象),但当前设置的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
相关产品推荐
相关产品推荐

