如何解决JavaScript - 显示从用户输入创建的对象实例
我正在构建一个用于存储用户书籍的图书馆应用。它应该接受用户输入,将其存储到一个数组中,然后将其显示在页面上。 如果我在数组中手动输入一些对象实例,则显示的值应该是(例如。标题:哈利波特,作者:JK 罗琳等),但我从用户输入创建的对象实例显示如下:
function() { return this.title + " by " + this.author + "," + this.pages + " pages," + this.read + "."; }
此外,即使我在按钮上设置了一个事件侦听器,也只创建了一个对象实例。 我做错了什么?
document.addEventListener("DOMContentLoaded",() => {
document.getElementById('submit').addEventListener("click",addBookToLibrary);
})
let myLibrary = [];
function Book(title,author,pages,read) {
this.title = title;
this.author = author;
this.pages = pages;
this.read = read;
this.info = function() {
return this.title + " by " + this.author + "," + this.read + ".";
}
}
function addBookToLibrary() {
let newBook = new Book();
newBook.title = document.getElementById("title").value;
newBook.author = document.getElementById("author").value;
newBook.pages = document.getElementById("pages").value;
newBook.read = document.getElementById("read").value;
myLibrary.push(newBook);
document.querySelector("form").reset(); // clear the form for the next entries
}
addBookToLibrary();
//loop through an array and display each book
function displayBooks() {
for (let i=0; i<myLibrary.length; i++) {
const booksdisplay = document.getElementById("books-display");
const cardBook = document.createElement('div');
cardBook.classList.add("grid-item");
cardBook.innerHTML += Object.values(myLibrary[i]).join(" ");
booksdisplay.appendChild(cardBook);
}
}
displayBooks();
<body>
<header>
</header>
<main>
<div id="page-wrapper">
<form id="new-book">
<label for="title">Title</label><br>
<input type="text" id="title" value=""/><br><br>
<label for="author">Author</label><br>
<input type="text" id="author" value=""/><br><br>
<label for="pages">Pages</label><br>
<input type="text" id="pages" value=""/><br><br>
<label for="read">Read</label><br>
<input type="checkBox" id="read" value=""/><br><br>
<button id="submit">Click to add</button>
</form> <br><br>
<div id="books-display"></div>
</div>
</main>
</body>
解决方法
有几个问题。首先,您没有阻止表单上的页面重新加载,因此,在页面重新加载时,js 设置的任何数据都将丢失。您需要将 e.preventDefault()
添加到 addBookToLibrary
函数中。
其次,您需要在添加新记录时调用 displayBooks
函数以重新呈现更新后的列表。您可以将函数调用放在 addBookToLibrary
函数中。
示例如下:
function addBookToLibrary(e) {
e.preventDefault()
let newBook = new Book();
newBook.title = document.getElementById("title").value;
newBook.author = document.getElementById("author").value;
newBook.pages = document.getElementById("pages").value;
newBook.read = document.getElementById("read").value;
myLibrary.push(newBook);
document.querySelector("form").reset(); // clear the form for the next entries
displayBooks();
}
第三,如果要打印值,只需调用 info
函数即可,无需使用 Object.values(...)
。例如,这里的 myLibrary[i]
是一个 Book
对象。由于您已经在 info
类中声明了一个方法 Book
,因此您可以调用该方法并根据该方法进行渲染。
替换
Object.values(myLibrary[i]).join(" ");
与
myLibrary[i].info();
示例:
//loop through an array and display each book
function displayBooks() {
const booksDisplay = document.getElementById("books-display");
booksDisplay.innerHTML = "";
for (let i=0; i<myLibrary.length; i++) {
const cardBook = document.createElement('div');
cardBook.classList.add("grid-item");
cardBook.innerHTML += myLibrary[i].info();
booksDisplay.appendChild(cardBook);
}
}
最后去掉addBookToLibrary
和displayBooks
的直接调用。 addBookToLibrary
仅应在用户提交表单时调用,而 displayBooks
仅应在通过表单提交添加新记录时调用。
这里是完整的设置
document.addEventListener("DOMContentLoaded",() => {
document.getElementById('submit').addEventListener("click",addBookToLibrary);
})
let myLibrary = [];
function Book(title,author,pages,read) {
this.title = title;
this.author = author;
this.pages = pages;
this.read = read;
this.info = function() {
return this.title + " by " + this.author + "," + this.pages + " pages," + this.read + ".";
}
}
function addBookToLibrary(e) {
e.preventDefault()
let newBook = new Book();
newBook.title = document.getElementById("title").value;
newBook.author = document.getElementById("author").value;
newBook.pages = document.getElementById("pages").value;
newBook.read = document.getElementById("read").value;
myLibrary.push(newBook);
document.querySelector("form").reset(); // clear the form for the next entries
displayBooks();
}
//loop through an array and display each book
function displayBooks() {
const booksDisplay = document.getElementById("books-display");
booksDisplay.innerHTML = ""; //clear the dom first
for (let i=0; i<myLibrary.length; i++) {
const cardBook = document.createElement('div');
cardBook.classList.add("grid-item");
cardBook.innerHTML += myLibrary[i].info();
booksDisplay.appendChild(cardBook);
}
}
<main>
<div id="page-wrapper">
<form id="new-book">
<label for="title">Title</label><br>
<input type="text" id="title" value=""/><br><br>
<label for="author">Author</label><br>
<input type="text" id="author" value=""/><br><br>
<label for="pages">Pages</label><br>
<input type="text" id="pages" value=""/><br><br>
<label for="read">Read</label><br>
<input type="checkbox" id="read" value=""/><br><br>
<button id="submit">Click to add</button>
</form> <br><br>
<div id="books-display"></div>
</div>
</main>
通过使用 // imports
const TableContainer = ({ db }) => {
const [data,setData] = useState([]);
useEffect(() => {
let didCancel = false;
parseData(db)
.then((dataFromServer) => (!didCancel && setData(dataFromServer)));
return () => { didCancel = true; }
},[db]);
// ...
对象,您可以节省一些时间在 Book 函数中写出所有这些元素 ID 和属性名称。
其他一些变化:
- 将
new FormData
方法移动到 Book 的原型。然后当您需要序列化数据时,它不会作为属性包含 - 您需要一个基于复选框的检查状态的布尔值真/假,而不是它的值
- 在表单上使用提交事件侦听器,而不是单击按钮。在回调中
info()
将是表单元素以简化诸如this
this.reset()
initDemo()
document.getElementById('new-book').addEventListener("submit",addBookToLibrary);
let myLibrary = [];
function Book(formData) {
const checkBoxes = ['read'];
for (let [k,v] of formData.entries()) {
this[k] = v
}
// boolean values for checkboxes
checkBoxes.forEach(k => this[k] = this[k] !== undefined);
}
Book.prototype.info = function() {
return this.title + " by " + this.author + "," + this.read + ".";
}
function addBookToLibrary(e) {
e.preventDefault();
let newBook = new Book(new FormData(this));
console.clear()
console.log(JSON.stringify(newBook,null,4));
myLibrary.push(newBook);
this.reset(); // clear the form for the next entries
displayBooks();
}
//loop through an array and display each book
function displayBooks() {
const booksDisplay = document.getElementById("books-display");
booksDisplay.innerHTML = ""; //clear the dom first
for (let i = 0; i < myLibrary.length; i++) {
const cardBook = document.createElement('div');
cardBook.classList.add("grid-item");
cardBook.innerHTML += myLibrary[i].info();
booksDisplay.appendChild(cardBook);
}
}
function initDemo(){
document.querySelectorAll('[data-value').forEach(el=>el.value = el.dataset.value)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。