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

函数可嵌套吗?图书馆项目changeColor失效及状态切换问题求助

问题分析与修复方案

核心问题列表

  • changeColor函数未执行:你定义了该函数但从未调用,导致颜色无变化。
  • DOM选择错误:document.querySelector(".card")仅会选中页面第一个.card元素,无法定位到点击按钮对应的目标卡片。
  • 循环语法错误:for (let i = 0; i < length.myLibrary; i++)写法错误,正确应为myLibrary.length。
  • 冗余代码:readStatus里的Book.prototype = Object.create(Book.prototype);和const toggleBook = new Book();完全没必要,直接修改数组内对象的属性即可。
  • 颜色设置时机错误:点击修改状态后调用displayOnPage()会重建所有卡片,此时在readStatus里设置颜色会被渲染覆盖,应该在渲染卡片时就根据read状态设置背景色。

修复后的完整代码

JavaScript部分

let myLibrary = [];

function Book(title, author, pages, read) {
  this.title = title;
  this.author = author;
  this.pages = pages;
  this.read = read;
}

function addBookToLibrary(title, author, pages, read) {
  let book = new Book(title, author, pages, read);
  myLibrary.push(book);
  displayOnPage();
}

function displayOnPage() {
  const books = document.querySelector(".books");

  const removeDivs = document.querySelectorAll(".card");
  for (let i = 0; i < removeDivs.length; i++) {
    removeDivs[i].remove();
  }

  let index = 0;
  myLibrary.forEach((book) => {
    let card = document.createElement("div");
    card.classList.add("card");
    // 渲染时直接根据read状态设置背景色
    card.style.backgroundColor = book.read === "yes" ? "green" : "red";
    books.appendChild(card);

    for (let key in book) {
      let para = document.createElement("p");
      para.textContent = `${key}: ${book[key]}`;
      card.appendChild(para);
    }

    let read_button = document.createElement("button");
    read_button.classList.add("read_button");
    read_button.textContent = "Toggle Read Status";
    read_button.dataset.linkedArray = index;
    card.appendChild(read_button);

    read_button.addEventListener("click", readStatus);

    let delete_button = document.createElement("button");
    delete_button.classList.add("delete_button");
    delete_button.textContent = "Remove";
    delete_button.dataset.linkedArray = index;
    card.appendChild(delete_button);

    delete_button.addEventListener("click", removeFromLibrary);

    function removeFromLibrary() {
      let retrieveBookToRemove = delete_button.dataset.linkedArray;
      myLibrary.splice(parseInt(retrieveBookToRemove), 1);
      displayOnPage();
    }

    function readStatus() {
      let bookIndex = parseInt(this.dataset.linkedArray);
      // 直接切换read状态,去掉冗余代码
      myLibrary[bookIndex].read = myLibrary[bookIndex].read === "yes" ? "no" : "yes";
      // 重新渲染页面,自动更新颜色
      displayOnPage();
    }

    index++;
  });
}

let add_book = document.querySelector(".add-book");
add_book.addEventListener("click", popUpForm);

function popUpForm() {
  document.getElementById("data-form").style.display = "block";
}

function closeForm() {
  document.getElementById("data-form").style.display = "none";
}

let close_form_button = document.querySelector("#close-form");
close_form_button.addEventListener("click", closeForm);

function intakeFormData() {
  let title = document.getElementById("title").value;
  let author = document.getElementById("author").value;
  let pages = document.getElementById("pages").value;
  let read = document.getElementById("read").value;

  if (title === "" || author === "" || pages === "" || read === "") {
    return;
  }

  addBookToLibrary(title, author, pages, read);
  document.getElementById("data-form").reset();
  closeForm(); // 提交后关闭表单
}

let submit_form = document.querySelector("#submit-form");
submit_form.addEventListener("click", function (event) {
  event.preventDefault();
  intakeFormData();
});

CSS部分(保持原代码)

* {
    margin: 0;
    padding: 0;
    background-color: rgb(245, 227, 205);
}

.books {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    text-align: center;
    margin: 20px;
    gap: 10px;
}

.card {
    border: 1px solid black;
    border-radius: 15px;
    padding: 10px;
}

.forms {
    display: flex;
    flex-direction: column;
    align-items: center;
}

form {
    margin-top: 20px;
}

select,
input[type="text"],
input[type="number"] {
    width: 100%;
    box-sizing: border-box;
}

.buttons-container {
    display: flex;
    margin-top: 10px;
}

.buttons-container button {
    width: 100%;
    margin: 2px;
}

.add-book {
    margin-top: 20px;
}

#data-form {
    display: none;
}

.read_button {
    margin-right: 10px;
}

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" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
</head>

<body>
    <div class="container">
        <div class="forms">
            <button class="add-book">Add Book To Library</button>
            <div class="pop-up">
                <form id="data-form">
                    <div class="form-container">
                        <label for="title">Title</label>
                        <input type="text" name="title" id="title" />
                    </div>

                    <div class="form-container">
                        <label for="author">Author</label>
                        <input type="text" name="author" id="author" />
                    </div>

                    <div class="form-container">
                        <label for="pages">Pages</label>
                        <input type="number" name="pages" id="pages" />
                    </div>

                    <div class="form-container">
                        <label for="read">Read</label>
                        <select name="read" id="read">
                            <option value="yes">Yes</option>
                            <option value="no">No</option>
                        </select>
                    </div>
                    <div class="buttons-container">
                        <button type="submit" id="submit-form">Submit Form</button>
                        <button type="button" id="close-form">Close Form</button>
                    </div>
                </form>
            </div>
        </div>
        <div class="books"></div>
    </div>
    <script src="script.js"></script>
</body>

</html>

关键修复说明

  1. 移除冗余代码:删掉readStatus中不必要的Book原型操作和空实例创建,直接修改数组内对应图书的read属性。
  2. 渲染时设置颜色:在displayOnPage创建卡片的同时,根据当前图书的read状态设置背景色,避免点击后设置被渲染覆盖的问题。
  3. 简化状态切换逻辑:用三元表达式一行完成read状态切换,代码更简洁。
  4. 修正索引获取方式:用this.dataset.linkedArray获取当前按钮对应的图书索引,比直接引用外部变量更可靠。
  5. 优化用户体验:在intakeFormData中添加closeForm(),提交表单后自动关闭弹窗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:40:35