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

如何用原生JS为数组对象生成对应卡片并解决卡片重复问题

当然可以仅通过原生JS修复该问题,问题根因非常明确:
你当前的populateBooks方法逻辑是,每次调用时都会遍历整个藏书数组,把所有书籍对应的卡片直接追加到容器末尾,但是没有清理容器中已经存在的旧书籍卡片,所以每次新增书籍后,旧卡片会重复生成一遍,叠加新卡片就出现了你遇到的重复问题。
另外注意你的表单卡片也放在books-wrapper容器内,清空旧卡片时不要误删表单。

你可以选择以下任意一种方案修改:

方案1:每次渲染前清空旧卡片(改造成本最低)

直接修改populateBooks函数,在遍历渲染前先删除所有已生成的书籍卡片即可:

function populateBooks(myLib, bookView) {
  // 新增:清空已有书籍卡片,保留表单卡片
  document.querySelectorAll('.book-card').forEach(card => card.remove());
  // 原有逻辑不变
  myLib.forEach((book, i) => {
    const card = `<div class="book-card" data-index=${i}>
                            <div class="card-info-wrapper">
                                 <h2>${book.title}</h2>
                                 <h3>${book.author}</h3>
                                 <h4>${book.pages} Pages</h4>
                                 <p>${book.info()}</p>
                                     <div class="button">
                                        Remove
                                     </div>
                            </div>
                        </div>`
    const element = document.createElement('div');
    element.innerHTML = card;
    bookView.appendChild(element.firstChild);
  });
};

该方案适合藏书数量不大的场景,改造成本极低。

方案2:仅渲染新增的单本藏书(性能更优)

拆分渲染逻辑,初始化时全量渲染所有藏书,新增藏书时只单独渲染新添加的那本,不需要每次遍历整个数组:

// 新增:单本藏书渲染方法
function renderSingleBook(book, index, bookView) {
  const card = `<div class="book-card" data-index=${index}>
    <div class="card-info-wrapper">
         <h2>${book.title}</h2>
         <h3>${book.author}</h3>
         <h4>${book.pages} Pages</h4>
         <p>${book.info()}</p>
             <div class="button">
                Remove
             </div>
    </div>
  </div>`
  const element = document.createElement('div');
  element.innerHTML = card;
  bookView.appendChild(element.firstChild);
}

// 修改原有全量渲染方法,复用单本渲染逻辑
function populateBooks(myLib, bookView) {
  document.querySelectorAll('.book-card').forEach(card => card.remove());
  myLib.forEach((book, i) => {
    renderSingleBook(book, i, bookView);
  });
};

// 修改新增藏书逻辑,不再全量渲染
function addToLibrary(e) {
  e.preventDefault();
  const title = (document.getElementById('title')).value;
  const author = (document.getElementById('author')).value;
  const pages = (document.getElementById('pages')).value;
  newBook = new Book(title, author, pages);

  myLibrary.push(newBook);
  // 仅渲染新增的最后一本
  renderSingleBook(newBook, myLibrary.length - 1, bookList);
  formDisplay();
  this.reset();
  console.table(myLibrary)
};

该方案适合藏书数量较大的场景,不会因为数组变长出现渲染卡顿。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:36:02