为什么我会收到单击任何按钮的警报消息? + 需要提示

Why am I getting the alert message for any buttons clicked? + Hints needed

基本上,我正在尝试添加功能,点击蓝色按钮后,阅读状态将变为 <Yes><Not>。在这种意义上的任何线索将不胜感激。其次,我不知道为什么在他们那一刻,单击该按钮时我会收到警报,这本书没有被删除(除非您单击正确的图标)但仍然......我无法弄清楚我们的缺陷按照我的逻辑!!

JS代码:

// Book Class: Represents a Book
class Book {
  constructor(title, author, pages, isRead) {
    this.title = title;
    this.author = author;
    this.pages = pages;
    this.isRead = isRead;
  }
}

// UI Class: Handle UI Tasks
class UI {
  static displayBooks() {
    const books = Store.getBooks();

    books.forEach((book) => UI.addBookToList(book));
  }

  static addBookToList(book) {
    const list = document.querySelector("#book-list");

    const row = document.createElement("tr");

    row.innerHTML = `
      <td>${book.title}</td> </button>
      <td>${book.author}</td>
      <td>${book.pages}</td>
      <td><button class="btn btn-sm btn-primary">${book.isRead}</button></td>
      <td><a href="#" class="btn btn-danger btn-sm delete">X</a></td>
    `;

    list.appendChild(row);
  }

  static deleteBook(el) {
    if (el.classList.contains("delete")) {
      el.parentElement.parentElement.remove();
    }
  }

  static showAlert(message, className) {
    const div = document.createElement("div");
    div.className = `alert alert-${className}`;
    div.appendChild(document.createTextNode(message));
    const container = document.querySelector(".container");
    const form = document.querySelector("#book-form");
    container.insertBefore(div, form);

    // Vanish in 3 seconds
    setTimeout(() => document.querySelector(".alert").remove(), 3000);
  }

  static clearFields() {
    document.querySelector("#title").value = "";
    document.querySelector("#author").value = "";
    document.querySelector("#pages").value = "";
    document.querySelector("#isRead").value = "";
  }
}

// Store Class: Handles Storage
class Store {
  static getBooks() {
    let books;
    if (localStorage.getItem("books") === null) {
      books = [];
    } else {
      books = JSON.parse(localStorage.getItem("books"));
    }

    return books;
  }

  static addBook(book) {
    const books = Store.getBooks();
    books.push(book);
    localStorage.setItem("books", JSON.stringify(books));
  }

  static removeBook(pages) {
    const books = Store.getBooks();

    books.forEach((book, index) => {
      if (book.pages === pages) {
        books.splice(index, 1);
      }
    });

    localStorage.setItem("books", JSON.stringify(books));
  }
}

// Event: Display Books
document.addEventListener("DOMContentLoaded", UI.displayBooks);

// Event: Add a Book
document.querySelector("#book-form").addEventListener("submit", (e) => {
  // Prevent actual submit
  e.preventDefault();

  // Get form values
  const title = document.querySelector("#title").value;
  const author = document.querySelector("#author").value;
  const pages = document.querySelector("#pages").value;
  const isRead = document.querySelector("#isRead").value;

  // Validate
  if (title === "" || author === "" || pages === "" || isRead === "") {
    UI.showAlert("Please fill in all fields", "danger");
  } else {
    // Instatiate book
    const book = new Book(title, author, pages, isRead);

    // Add Book to UI
    UI.addBookToList(book);

    // Add book to store
    Store.addBook(book);

    // Show success message
    UI.showAlert("Book Added", "success");

    // Clear fields
    UI.clearFields();
  }
});

// Event: Remove a Book
document.querySelector("#book-list").addEventListener("click", (e) => {
  // Remove book from UI
  UI.deleteBook(e.target);

  // Remove book from store
  Store.removeBook(
    e.target.parentElement.previousElementSibling.previousElementSibling
      .textContent
  );

  // Show success message
  UI.showAlert("Book Removed", "success");
});

HTML代码:

!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>My BookListApp</title>
    <link
      rel="stylesheet"
      href="https://bootswatch.com/4/yeti/bootstrap.min.css"
    />
    <link
      rel="stylesheet"
      href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"
      integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm"
      crossorigin="anonymous"
    />
  </head>
  <body>
    <div class="container mt-4">
      <h1 class="display-4 text-center">
        <i class="fas fa-book-open text-primary"></i>My
        <span class="text-primary">BookList</span> App
      </h1>
      <form id="book-form">
        <div class="form-group">
          <label for="title">Title:</label>
          <input type="text" id="title" class="form-control" maxlength="30" />
        </div>
        <div class="form-group">
          <label for="author">Author:</label>
          <input type="text" id="author" class="form-control" maxlength="20" />
        </div>
        <div class="form-group">
          <label for="pages">Pages:</label>
          <input
            type="number"
            id="pages"
            class="form-control"
            min="1"
            max="10000"
          />
        </div>
        <div class="form-group">
          <label for="isRead">Read:</label>
          <select type="number" id="isRead" class="form-control">
            <option value="" selected disabled hidden></option>
            <option value="Yes">Yes</option>
            <option value="No">No</option>
          </select>
        </div>
        <input
          type="submit"
          value="Add Book"
          class="btn btn-primary btn-block"
        />
      </form>
      <table class="table table-striped mt-5">
        <thead>
          <tr>
            <th>Title:</th>
            <th>Author:</th>
            <th>Pages:</th>
            <th>Read:</th>
            <th></th>
          </tr>
        </thead>
        <tbody id="book-list"></tbody>
      </table>
    </div>

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

谢谢!

这个 onclick 太宽泛了:

document.querySelector("#book-list").addEventListener("click",

每次点击书籍中的任何地方都会触发它 list/table。不只是在按钮上。任何地方。如果你不点击按钮,JS 就会崩溃。如果您点击 Yes/No 按钮,JS 不会中断,但它会 尝试 删除这本书,有点。

损坏 jsfiddle:https://jsfiddle.net/do42Lkqn/

解决方案:明确检查单击了哪个按钮。在点击处理程序中,您可以执行以下操作:

if (!e.target.closest('.delete')) return;

因此,如果您没有单击 .delete 元素,它不会执行任何操作。