You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Odin Project图书管理Web应用:表单提交后数组元素消失问题求助

问题排查与解决方案

嘿,我一眼就看出问题出在哪了——表单的默认提交行为在搞鬼

问题根源

当你点击submit按钮时,浏览器会默认执行表单的提交逻辑:把表单数据发送到action属性指定的地址(这里action为空,所以就是当前页面),然后刷新整个页面。页面一刷新,你的所有JavaScript代码会重新执行:

  • myLibrary数组被重新初始化为空数组[]
  • 接着只运行那三个预设的addBookToLibrary("The Hobbit", "Tolkien")调用
    所以你刚通过表单添加的图书看起来“消失”了,其实是页面重置后数组回到了初始状态。

而你直接在JS里调用addBookToLibrary时,没有触发表单提交,页面不会刷新,数组数据一直保存在内存里,所以一切正常。

解决方案

1. 阻止表单的默认提交行为

推荐使用标准的事件监听方式处理表单提交,而不是依赖按钮的onclick属性,这样代码更健壮:

修改你的JavaScript代码,替换原来的addButtonaddyWaddy相关代码:

// 获取表单元素
const newBookForm = document.querySelector("#newBookForm");
// 监听表单的submit事件
newBookForm.addEventListener("submit", function(e) {
  // 核心:阻止表单默认的提交刷新行为
  e.preventDefault();
  
  // 获取输入框的值
  const title = document.querySelector("#newTitle").value;
  const author = document.querySelector("#newAuthor").value;
  
  // 添加图书到库
  addBookToLibrary(title, author);
  
  // 可选:提交后清空表单输入,提升用户体验
  newBookForm.reset();
});

然后删除HTML中submit按钮的onclick="addyWaddy()"属性:

<input type="submit" id="submitButton" value="Submit">

2. 修复render函数的小问题

你的render函数存在两个小隐患:

  • book变量没有用let/const声明,会变成全局变量,可能引发意外问题
  • 模板字符串里的HTML转义符&lt;/&gt;不需要保留,直接用</>即可

修改后的render函数:

function render() {
  const book = myLibrary[myLibrary.length - 1];
  table.innerHTML += `<tr class="bookEntry"><td>${book.title}</td><td>${book.author}</td></tr>`;
}

修改后的完整代码

JavaScript

let myLibrary = [];
const table = document.querySelector("#libraryTable");

// 图书构造函数
function Book(title, author) {
  this.title = title;
  this.author = author;
}

// 添加图书到库
function addBookToLibrary(title, author) {
  let newBook = new Book(title, author);
  myLibrary.push(newBook);
  render();
}

// 渲染最后添加的图书到表格
function render() {
  const book = myLibrary[myLibrary.length - 1];
  table.innerHTML += `<tr class="bookEntry"><td>${book.title}</td><td>${book.author}</td></tr>`;
}

// 初始化示例图书
addBookToLibrary("The Hobbit", "Tolkien");
addBookToLibrary("The Hobbit", "Tolkien");
addBookToLibrary("The Hobbit", "Tolkien");

// 表单提交处理
const newBookForm = document.querySelector("#newBookForm");
newBookForm.addEventListener("submit", function(e) {
  e.preventDefault();
  const title = document.querySelector("#newTitle").value;
  const author = document.querySelector("#newAuthor").value;
  addBookToLibrary(title, author);
  newBookForm.reset();
});

HTML

<div id="container">
  <div class="grid-item" id="leftSide">
    <h1>Add books here</h1>
    <form action="" id="newBookForm">
      <input type="text" id="newTitle" placeholder="Insert book title" name="titleName">
      <input type="text" id="newAuthor" placeholder="Insert book author" name="authorName">
      <br>
      <input type="submit" id="submitButton" value="Submit">
    </form>
  </div>
  <div class="grid-item" id="rightSide">
    <h1>Books go here</h1>
    <table id="libraryTable">
      <tr>
        <th>Title</th>
        <th>Author</th>
      </tr>
    </table>
  </div>
</div>

(顺便把输入框的value改成了placeholder,这样用户点击输入时默认提示文字会自动消失,体验更好)

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

火山引擎 最新活动