Odin Project图书管理Web应用:表单提交后数组元素消失问题求助
问题排查与解决方案
嘿,我一眼就看出问题出在哪了——表单的默认提交行为在搞鬼!
问题根源
当你点击submit按钮时,浏览器会默认执行表单的提交逻辑:把表单数据发送到action属性指定的地址(这里action为空,所以就是当前页面),然后刷新整个页面。页面一刷新,你的所有JavaScript代码会重新执行:
myLibrary数组被重新初始化为空数组[]- 接着只运行那三个预设的
addBookToLibrary("The Hobbit", "Tolkien")调用
所以你刚通过表单添加的图书看起来“消失”了,其实是页面重置后数组回到了初始状态。
而你直接在JS里调用addBookToLibrary时,没有触发表单提交,页面不会刷新,数组数据一直保存在内存里,所以一切正常。
解决方案
1. 阻止表单的默认提交行为
推荐使用标准的事件监听方式处理表单提交,而不是依赖按钮的onclick属性,这样代码更健壮:
修改你的JavaScript代码,替换原来的addButton和addyWaddy相关代码:
// 获取表单元素 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转义符
</>不需要保留,直接用</>即可
修改后的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




