【问题标题】:How to generate multiple card for each object in an array?如何为数组中的每个对象生成多张卡片?
【发布时间】:2021-10-30 05:32:51
【问题描述】:

@font-face {
    font-family: "fanwood";
    font-style: normal;
    font-weight: normal;
    src: url("fonts/Fanwood.otf");
    font-display: swap;
}

:root {
    --color-primary: #e9e2d7;
    --color-primary-alt: #8e6549;
    --color-secondary: #d42257;
    --color-background: #d2fbf7;
    --color-text: #412d86;
    --color-light: #fff;
    --color-anchor: #3a00ff;
    --font-family: "fanwoood";
    --font-weight-strong: 500;
    --font-size-h1: 4rem;
    --font-size-h2: 3rem;
    --font-size-h3: 2rem;
    --font-size-h4: 1.35rem;
    --font-size-text: 1.15rem;
    --border-radius: 8px;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}


/* Remove default margin */

body,
h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 0;
}

html {
    overflow-x: hidden;
}


/* Set core body defaults */

body {
    font-family: 'fanwood';
    min-height: 100vh;
    font-size: 100%;
    line-height: 1.5;
    text-rendering: optimizeSpeed;
    overflow-x: hidden;
}


/* Make images easier to work with */

img {
    display: block;
    max-width: 100%;
}


/* Inherit fonts for inputs and buttons */

input,
button,
textarea,
select {
    font: inherit;
}

body {
    background-color: var(--color-primary);
}

button {
    background-color: var(--color-primary);
    border: none;
    margin: 0;
}

input {
    width: 100%;
    margin-bottom: 10px 0;
}

.site-wrapper {
    margin: 0 4%;
}

.card-info-wrapper {
    margin: 4% 4%;
}

.header {
    color: var(--color-primary);
    background-color: var(--color-primary-alt);
    height: 84px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.tool-bar {
    margin-top: 20px;
}

.tools {
    display: flex;
}

.button {
    cursor: pointer;
    display: inline-flex;
    padding: 2px 8px;
    color: var(--color-primary-alt);
    background-color: var(--color-primary);
}

.button.add {
    display: inline-flex;
    padding: 2px 8px;
    background-color: var(--color-primary-alt);
    color: var(--color-primary);
}

.books-wrapper {
    margin-top: 20px;
    /* border: 1px solid white; */
    display: flex;
    flex-wrap: wrap;
}

.book-card {
    word-wrap: normal;
    background-color: var(--color-primary-alt);
    color: var(--color-primary);
    width: 300px;
    height: 350px;
    margin-right: 10px;
    margin-bottom: 10px;
}

.form-card {
    display: none;
    word-wrap: normal;
    background-color: var(--color-primary-alt);
    color: var(--color-primary);
    width: 300px;
    height: 350px;
    margin-right: 10px;
    margin-bottom: 10px;
}

.toggle-on {
    display: block;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Book</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>

    <div class="header">
        <div class="site-wrapper">
            <div class="header-logo-container">
                <h1>Library</h1>
            </div>
        </div>
    </div>

    <div class="tool-bar">
        <div class="site-wrapper">
            <div class="tools">
                <div class="button add" id="add-form">
                    Add Book
                </div>
            </div>
        </div>
    </div>
    <div class="books">
        <div class="site-wrapper">
            <div class="books-wrapper">
                <!-- TEMPLATE FOR BOOK CARD -->
                <!-- <div class="book-card"> 
                    <div class="card-info-wrapper">
                        <h2>Title</h2>
                        <h3>Author</h3>
                        <h4>Pages</h4>
                        <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ipsum fugit officiis animi soluta et, sit aliquid.</p>
                        <div class="button">
                            Remove
                        </div>
                    </div>
                </div> -->
                <div class="form-card">
                    <div class="card-info-wrapper">
                        <form id="input-form">
                            <label for="title"><h3>Title</h3></label>
                            <input type="text" id="title" name="title" placeholder="Name of the Book" required>

                            <label for="author"><h3>Author</h3></label>
                            <input type="text" id="author" name="author" placeholder="Name of the Author" required>

                            <label for="pages"><h3>Pages</h3></label>
                            <input type="number" id="pages" name="pages" placeholder="Number of Pages" required>

                            <button type="submit" class="button" id="addBook">Add Book</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="app.js"></script>
</body>

</html>

我想为数组中的每个对象生成多张卡片。我面临的问题是,每次添加新对象时,都会生成数组中现有对象的重复卡。有什么方法可以通过使用 vanilla js 来解决它?

https://i.stack.imgur.com/EsApw.png

const form = document.getElementById('input-form');
const formButton = document.getElementById('add-form');
const formView = document.querySelector('.form-card')
const bookList = document.querySelector('.books-wrapper');
const bookCard = document.querySelector('.book-card');

let myLibrary = [];
let newBook;

function Book(title, author, pages) {
  this.title = title;
  this.author = author;
  this.pages = pages;
  this.info = function() {
    return `${this.title} is a book by ${this.author}, ${this.pages} pages, not read yet.`
  };
};
Book.prototype.read = false;

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);
  populateBooks(myLibrary, bookList);
  formDisplay();
  this.reset();
  console.table(myLibrary)
};

function populateBooks(myLib, bookView) {
  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);

  });

};
function formDisplay() {
formView.classList.toggle('toggle-on');
};
formButton.addEventListener('click', formDisplay);
populateBooks(myLibrary, bookList);
[enter image description here][1]

【问题讨论】:

    标签: javascript html arrays object dynamically-generated


    【解决方案1】:

    您将整个图书馆再次附加到已填充的 div 中。

    您的解决方案很简单,只需在再次附加所有内容之前清理您的书籍 div。

    这里是你的 JS 修改和工作:

    const form = document.getElementById('input-form');
    const formButton = document.getElementById('add-form');
    const formView = document.querySelector('.form-card')
    const bookList = document.querySelector('.books-wrapper');
    const bookCard = document.querySelector('.book-card');
    
    let myLibrary = [];
    let newBook;
    
    function Book(title, author, pages) {
      this.title = title;
      this.author = author;
      this.pages = pages;
      this.info = function() {
        return `${this.title} is a book by ${this.author}, ${this.pages} pages, not read yet.`
      };
    };
    Book.prototype.read = false;
    
    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);
      populateBooks(myLibrary, bookList);
      formDisplay();
      this.reset();
      console.table(myLibrary)
    };
    
    function populateBooks(myLib, bookView) {
      bookList.innerHTML = "";
      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);
    
      });
    
    }
    
    document.addEventListener("DOMContentLoaded", function() {
        form.addEventListener("submit", function(e) {
            addToLibrary(e)
        });
    });
    

    我修改了一些部分以使其在本地工作,因为您没有发布您的 HTML。

    我添加的行是:

    bookList.innerHTML = "";
    

    就在您的 populateBooks 函数的开头。

    编辑:可以使用更新后的代码,Here is the JSFiddle with your full code modified to working.

    问题是添加命令 document.querySelectorAll('.book-card').forEach(e =&gt; e.remove()); 以删除 div 中所有已渲染的书籍,因此当您运行函数时,它将仅删除书籍,然后再次正确渲染。

    【讨论】:

    • 感谢您的回复。我了解发生了什么,但是当我添加该行时,表单由于某种原因无法正常工作,请添加 html 代码。这也是解决这个问题的正确方法吗?我还有其他方法可以做同样的事情吗?
    • 删除了我的其他评论。现在看到你的完整代码我错了。它工作所需的代码是在渲染其他书的函数之前删除所有书卡 div。 Here is a JS fiddle with all your code now fully working
    • 我还更新了我的答案以反映实际的解决方案。
    • 谢谢,它现在工作正常。我还有一个问题,是实现这个的正确方法还是只是对坏代码的一些快速修复?这个项目在 TOP 的课程中​​,其他大多数学生 sol 正在用 js 创建 dom 元素,这让我想知道这是否是实现这个功能的正确方法。
    • 处理 DOM 元素基本上没有“正确”或“错误”的方式。只有一种方式可以促进您的互动,而其他方式可能会使其将来难以维护。建议在 JS 中手动创建 DOM 元素,因为它更易于修改和使用,以防您需要为您的应用程序实现新功能。但你的方式肯定不是“错误的”。
    猜你喜欢
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多