如何让handleDelete函数正确获取并移除Library数组指定元素?
问题修复方案
核心问题拆解
你的代码存在几个关键问题导致删除功能失效:
- 索引获取方式不稳定:依赖
e.path[1].attributes[1]获取索引,DOM结构变化会直接导致获取失败,逻辑不严谨。 - 数组操作错误:使用
find方法只能匹配元素,无法生成移除目标项后的新数组。 - 索引与数组脱节:全局
count变量维护的data-target值,会随着重复渲染与数组实际索引不匹配。 - 重复渲染问题:
viewBookList每次调用未清空现有卡片,导致DOM重复添加元素。 - 构造函数错误:
Book构造函数返回bookInfo()(无返回值),导致实例化的Book对象为undefined,无法正确存入数组。 - 错误清空数组:
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
相关产品推荐
相关产品推荐

