Javascript - 为 DOM 个创建的元素创建切换函数
Javascript - Create Toggle function for DOM created elements
我有一个按钮“-”,当点击它时,它会在我的“书籍”的一角创建一个“X”按钮来删除它们。有没有办法让它在我再次单击“-”按钮时在隐藏和显示“书籍”一角的“X”按钮之间切换?
没有JQuery拜托,还没学会怎么用
这是我的 HTML:
<div class="container">
<div class="book-display">
<div class="title">Title:</div>
<div class="author">Author:</div>
<div class="pages">Pages:</div>
<div class="read">Have Read:</div>
</div>
<div class="shelf"></div>
<div class="buttons">
<button class="button" id="delete">➖</button>
<button class="button" id="add">➕</button>
</div>
这是我的 Javascript:
//Add Books to Shelf Display
function addBookToShelf() {
for (let i = 0; i < myLibrary.length; i++) {
const books = document.createElement('div');
books.classList.add('books');
books.setAttribute('id', myLibrary[i].title)
if (myLibrary[i].read === "Not Read") {
books.style.background = "rgba(71, 22, 10, 0.664)"
};
if (myLibrary[i].read === "Partially Read") {
books.style.background = "rgba(199, 199, 58, 0.575)"
}
const booksText = document.createElement('div');
booksText.classList.add('book-text')
booksText.addEventListener('click', () => {
bookTitleEl.innerHTML = "Title: " + myLibrary[i].title;
bookAuthorEl.innerHTML = "Author: " + myLibrary[i].author;
bookPagesEl.innerHTML = "Pages: " + myLibrary[i].pages;
bookReadEl.innerHTML = "Have Read: " + myLibrary[i].read;
});
booksText.innerHTML = myLibrary[i].title;
shelfEl.appendChild(books);
books.appendChild(booksText);
document.getElementById(myLibrary[i].title).setAttribute('value', 1);
//Add delete button to books function
function deleteXButton() {
const deleteXEl = document.createElement('button');
deleteXEl.classList.add('deleteX');
books.appendChild(deleteXEl);
deleteXEl.innerHTML = "X"
document.getElementsByClassName('deleteX');
if (document.getElementsByClassName('deleteX').length > myLibrary.length) {
deleteXEl.remove();
}
if (deleteXEl.style.display === "block") {
deleteXEl.style.display = "none";
} else {
deleteXEl.style.display = "block";
}
//Delete Book from Shelf & Object from Libray Array
deleteXEl.addEventListener('click', () => {
const bookIndex = myLibrary.indexOf(myLibrary[i])
books.remove(delete myLibrary[bookIndex]);
noBookFound();
});
}
//DELETE BUTTON EVENT LISTENER
deleteButtonEl.addEventListener('click', () => {
deleteXButton();
});
}
};
任何帮助将不胜感激!
classList API 有一个切换方法,我们可以使用它来切换样式。如果您包含从 DOM 中删除元素的 class(与 display: none
一样),这将成为 hide/show 您的元素响应用户操作的简单方法。您可以在代码段 的 toggleDeleteButtons
函数中查看其工作原理 。
我对您的代码进行了一系列其他建议的修改,您可以根据需要自由选择。顺便说一句,上面的 link 转到 MDN,这是一个搜索任何不熟悉的网络开发术语的好网站(例如,您只需 google“ MDN findIndex" 了解数组的 findIndex
方法。)
// Identifies some DOM elements globally
const
deleteBooksButton = document.getElementById("delete"),
addBookButton = document.getElementById("add"),
shelfEl = document.getElementsByClassName("shelf")[0],
deleteButtons = document.getElementsByClassName("delete-button");
// Declares the library globally, and populates it with sample books
let library;
library = getSampleLibrary(library);
addBooksToShelf(library);
// Calls toggleDeleteButtons when deleteBooksButton is clicked
deleteBooksButton.addEventListener("click", toggleDeleteButtons);
// Calls deleteBook when anything inside shelf is clicked
shelfEl.addEventListener("click", deleteBook);
// Defines function to show/hide all delete buttons
function toggleDeleteButtons(){
for(let button of deleteButtons){
button.classList.toggle("hidden");
}
}
// Defines function to delete a book (Click events bubble up to `shelf`)
function deleteBook(event){
// Makes sure the click event was on a delete-button before proceeding
const clickedThing = event.target;
if(!clickedThing.classList.contains("delete-button")){ return; }
// Searches upward in DOM tree for bookEl, then downward for title
const
bookEl = clickedThing.closest(".book"),
title = bookEl.querySelector(".title").textContent;
// Removes bookEl from the DOM tree
bookEl.remove();
// Looks in library array for book object with matching title property
const libraryIndex = library.findIndex(book => book.title == title);
// Removes book object from library if there was a match
if(libraryIndex > -1){
library.splice(libraryIndex, 1);
}
}
// Defines function to populate shelf's DOM tree with book-related elements
function addBooksToShelf(library) {
// Loops through elements of library array (referring to each as `book`)
for (let book of library) {
// Uses "destructuring" to get local variables bound to props of book
const { title, author, pages, read } = book;
// Creates bookEl and its descendants
// bookEl will have 3 children: deleteDiv, teaserEl, and detailsEl
// deleteDiv will have 1 child: deleteButton
// detailsEl will have 4 div children (title, author, pages, and read)
// (The 4 divs inside detailsEl will each have 1 span child)
const
bookEl = document.createElement("div"), // Will have class: "book"
deleteDiv = document.createElement("div"), // ... "delete-div"
teaserEl = document.createElement("div"), // ... "teaser"
detailsEl = document.createElement("div"), // ... "text"
titleDiv = document.createElement("div"),
authorDiv = document.createElement("div"),
pagesDiv = document.createElement("div"),
readDiv = document.createElement("div"),
titleSpan = document.createElement("span"), // ... "title"
authorSpan = document.createElement("span"), // ... "author"
pagesSpan = document.createElement("span"), // ... "pages"
readSpan = document.createElement("span"); // ... "read"
// Creates and configures deleteButton, and appends it to deleteDiv
deleteButton = document.createElement("button");
deleteButton.classList.add("delete-button");
deleteButton.classList.add("hidden");
deleteButton.textContent = "X";
deleteDiv.appendChild(deleteButton);
// Configures deleteDiv, and appends it to bookEl
deleteDiv.classList.add("delete-div");
bookEl.appendChild(deleteDiv);
// Configures teaserEl, and appends it to bookEl
teaserEl.innerHTML = title;
teaserEl.classList.add("teaser"); // teaser class
bookEl.appendChild(teaserEl);
// Configures the spans
titleSpan.classList.add("title");
authorSpan.classList.add("author");
pagesSpan.classList.add("pages");
readSpan.classList.add("read");
titleSpan.textContent = title;
authorSpan.textContent = author;
pagesSpan.textContent = pages;
readSpan.textContent = read;
// Populates divs (w/ label text and spans), and adds them to detailsEl
titleDiv.innerHTML = "Title: " + titleSpan.outerHTML;
authorDiv.innerHTML = "Author: " + authorSpan.outerHTML
pagesDiv.innerHTML = "Pages: " + pagesSpan.outerHTML
readDiv.innerHTML = "Have Read: " + readSpan.outerHTML
detailsEl.appendChild(titleDiv);
detailsEl.appendChild(authorDiv);
detailsEl.appendChild(pagesDiv);
detailsEl.appendChild(readDiv);
// Configures detailsEl, and appends it to bookEl
detailsEl.classList.add('text'); // text class
detailsEl.classList.add("hidden"); // detailsEl & children are hidden
bookEl.appendChild(detailsEl);
// Configures bookEl (w/ styles, listener, etc), and adds it to shelf
const
readBG = "rgba(22, 71, 10, 0.420)",
notReadBG = "rgba(71, 22, 10, 0.664)",
partReadBG = "rgba(199, 199, 58, 0.575)";
if (read === "Partially Read") { bookEl.style.background = partReadBG; }
else if (read === "Not Read") { bookEl.style.background = notReadBG; }
else { bookEl.style.background = readBG; }
bookEl.id = title; // (Careful: Book titles are not unique identifiers!)
bookEl.classList.add("book");
bookEl.setAttribute("data-value", 1); // (Custom attributes use "data-")
bookEl.addEventListener('click', toggleText); // Listener on book
shelfEl.appendChild(bookEl);
}
};
// Defines function to show text and hide teaser (or vice versa)
function toggleText(event){
// Searches upward in DOM tree (from clicked element) to get closest book
const bookEl = event.target.closest(".book");
// Searches downward in DOM tree to find teaser & text, and update classes
bookEl.querySelector(".teaser").classList.toggle("hidden");
bookEl.querySelector(".text").classList.toggle("hidden");
}
// Defines function to return a sample library
function getSampleLibrary(library){
const sampleLibrary = [
{
title: "Harry Potter and the Methods of Rationality",
author: "Yudkowsky, Eliezer",
pages: 750,
read: "Read"
},
{
title: "Go, Dog. Go!",
author: "Eastman, P.D.",
pages: 16,
read: "Partially Read"
}
];
library = sampleLibrary;
return library;
}
.shelf{ width: 350px; }
.book{ margin-top: 0.5em; padding: 0.5em; }
.delete-div{ text-align: right; } /* divs exist only to align buttons */
.delete-button{ border: 1px solid grey; border-radius: 0.3em; }
.hidden{ display: none; }
<div class="container">
<div class="buttons">
<button id="delete">Delete Books ➖</button>
<button class="button" id="add">Add Book ➕</button>
</div>
<div class="shelf"></div>
</div>
我有一个按钮“-”,当点击它时,它会在我的“书籍”的一角创建一个“X”按钮来删除它们。有没有办法让它在我再次单击“-”按钮时在隐藏和显示“书籍”一角的“X”按钮之间切换?
没有JQuery拜托,还没学会怎么用
这是我的 HTML:
<div class="container">
<div class="book-display">
<div class="title">Title:</div>
<div class="author">Author:</div>
<div class="pages">Pages:</div>
<div class="read">Have Read:</div>
</div>
<div class="shelf"></div>
<div class="buttons">
<button class="button" id="delete">➖</button>
<button class="button" id="add">➕</button>
</div>
这是我的 Javascript:
//Add Books to Shelf Display
function addBookToShelf() {
for (let i = 0; i < myLibrary.length; i++) {
const books = document.createElement('div');
books.classList.add('books');
books.setAttribute('id', myLibrary[i].title)
if (myLibrary[i].read === "Not Read") {
books.style.background = "rgba(71, 22, 10, 0.664)"
};
if (myLibrary[i].read === "Partially Read") {
books.style.background = "rgba(199, 199, 58, 0.575)"
}
const booksText = document.createElement('div');
booksText.classList.add('book-text')
booksText.addEventListener('click', () => {
bookTitleEl.innerHTML = "Title: " + myLibrary[i].title;
bookAuthorEl.innerHTML = "Author: " + myLibrary[i].author;
bookPagesEl.innerHTML = "Pages: " + myLibrary[i].pages;
bookReadEl.innerHTML = "Have Read: " + myLibrary[i].read;
});
booksText.innerHTML = myLibrary[i].title;
shelfEl.appendChild(books);
books.appendChild(booksText);
document.getElementById(myLibrary[i].title).setAttribute('value', 1);
//Add delete button to books function
function deleteXButton() {
const deleteXEl = document.createElement('button');
deleteXEl.classList.add('deleteX');
books.appendChild(deleteXEl);
deleteXEl.innerHTML = "X"
document.getElementsByClassName('deleteX');
if (document.getElementsByClassName('deleteX').length > myLibrary.length) {
deleteXEl.remove();
}
if (deleteXEl.style.display === "block") {
deleteXEl.style.display = "none";
} else {
deleteXEl.style.display = "block";
}
//Delete Book from Shelf & Object from Libray Array
deleteXEl.addEventListener('click', () => {
const bookIndex = myLibrary.indexOf(myLibrary[i])
books.remove(delete myLibrary[bookIndex]);
noBookFound();
});
}
//DELETE BUTTON EVENT LISTENER
deleteButtonEl.addEventListener('click', () => {
deleteXButton();
});
}
};
任何帮助将不胜感激!
classList API 有一个切换方法,我们可以使用它来切换样式。如果您包含从 DOM 中删除元素的 class(与 display: none
一样),这将成为 hide/show 您的元素响应用户操作的简单方法。您可以在代码段 的 toggleDeleteButtons
函数中查看其工作原理 。
我对您的代码进行了一系列其他建议的修改,您可以根据需要自由选择。顺便说一句,上面的 link 转到 MDN,这是一个搜索任何不熟悉的网络开发术语的好网站(例如,您只需 google“ MDN findIndex" 了解数组的 findIndex
方法。)
// Identifies some DOM elements globally
const
deleteBooksButton = document.getElementById("delete"),
addBookButton = document.getElementById("add"),
shelfEl = document.getElementsByClassName("shelf")[0],
deleteButtons = document.getElementsByClassName("delete-button");
// Declares the library globally, and populates it with sample books
let library;
library = getSampleLibrary(library);
addBooksToShelf(library);
// Calls toggleDeleteButtons when deleteBooksButton is clicked
deleteBooksButton.addEventListener("click", toggleDeleteButtons);
// Calls deleteBook when anything inside shelf is clicked
shelfEl.addEventListener("click", deleteBook);
// Defines function to show/hide all delete buttons
function toggleDeleteButtons(){
for(let button of deleteButtons){
button.classList.toggle("hidden");
}
}
// Defines function to delete a book (Click events bubble up to `shelf`)
function deleteBook(event){
// Makes sure the click event was on a delete-button before proceeding
const clickedThing = event.target;
if(!clickedThing.classList.contains("delete-button")){ return; }
// Searches upward in DOM tree for bookEl, then downward for title
const
bookEl = clickedThing.closest(".book"),
title = bookEl.querySelector(".title").textContent;
// Removes bookEl from the DOM tree
bookEl.remove();
// Looks in library array for book object with matching title property
const libraryIndex = library.findIndex(book => book.title == title);
// Removes book object from library if there was a match
if(libraryIndex > -1){
library.splice(libraryIndex, 1);
}
}
// Defines function to populate shelf's DOM tree with book-related elements
function addBooksToShelf(library) {
// Loops through elements of library array (referring to each as `book`)
for (let book of library) {
// Uses "destructuring" to get local variables bound to props of book
const { title, author, pages, read } = book;
// Creates bookEl and its descendants
// bookEl will have 3 children: deleteDiv, teaserEl, and detailsEl
// deleteDiv will have 1 child: deleteButton
// detailsEl will have 4 div children (title, author, pages, and read)
// (The 4 divs inside detailsEl will each have 1 span child)
const
bookEl = document.createElement("div"), // Will have class: "book"
deleteDiv = document.createElement("div"), // ... "delete-div"
teaserEl = document.createElement("div"), // ... "teaser"
detailsEl = document.createElement("div"), // ... "text"
titleDiv = document.createElement("div"),
authorDiv = document.createElement("div"),
pagesDiv = document.createElement("div"),
readDiv = document.createElement("div"),
titleSpan = document.createElement("span"), // ... "title"
authorSpan = document.createElement("span"), // ... "author"
pagesSpan = document.createElement("span"), // ... "pages"
readSpan = document.createElement("span"); // ... "read"
// Creates and configures deleteButton, and appends it to deleteDiv
deleteButton = document.createElement("button");
deleteButton.classList.add("delete-button");
deleteButton.classList.add("hidden");
deleteButton.textContent = "X";
deleteDiv.appendChild(deleteButton);
// Configures deleteDiv, and appends it to bookEl
deleteDiv.classList.add("delete-div");
bookEl.appendChild(deleteDiv);
// Configures teaserEl, and appends it to bookEl
teaserEl.innerHTML = title;
teaserEl.classList.add("teaser"); // teaser class
bookEl.appendChild(teaserEl);
// Configures the spans
titleSpan.classList.add("title");
authorSpan.classList.add("author");
pagesSpan.classList.add("pages");
readSpan.classList.add("read");
titleSpan.textContent = title;
authorSpan.textContent = author;
pagesSpan.textContent = pages;
readSpan.textContent = read;
// Populates divs (w/ label text and spans), and adds them to detailsEl
titleDiv.innerHTML = "Title: " + titleSpan.outerHTML;
authorDiv.innerHTML = "Author: " + authorSpan.outerHTML
pagesDiv.innerHTML = "Pages: " + pagesSpan.outerHTML
readDiv.innerHTML = "Have Read: " + readSpan.outerHTML
detailsEl.appendChild(titleDiv);
detailsEl.appendChild(authorDiv);
detailsEl.appendChild(pagesDiv);
detailsEl.appendChild(readDiv);
// Configures detailsEl, and appends it to bookEl
detailsEl.classList.add('text'); // text class
detailsEl.classList.add("hidden"); // detailsEl & children are hidden
bookEl.appendChild(detailsEl);
// Configures bookEl (w/ styles, listener, etc), and adds it to shelf
const
readBG = "rgba(22, 71, 10, 0.420)",
notReadBG = "rgba(71, 22, 10, 0.664)",
partReadBG = "rgba(199, 199, 58, 0.575)";
if (read === "Partially Read") { bookEl.style.background = partReadBG; }
else if (read === "Not Read") { bookEl.style.background = notReadBG; }
else { bookEl.style.background = readBG; }
bookEl.id = title; // (Careful: Book titles are not unique identifiers!)
bookEl.classList.add("book");
bookEl.setAttribute("data-value", 1); // (Custom attributes use "data-")
bookEl.addEventListener('click', toggleText); // Listener on book
shelfEl.appendChild(bookEl);
}
};
// Defines function to show text and hide teaser (or vice versa)
function toggleText(event){
// Searches upward in DOM tree (from clicked element) to get closest book
const bookEl = event.target.closest(".book");
// Searches downward in DOM tree to find teaser & text, and update classes
bookEl.querySelector(".teaser").classList.toggle("hidden");
bookEl.querySelector(".text").classList.toggle("hidden");
}
// Defines function to return a sample library
function getSampleLibrary(library){
const sampleLibrary = [
{
title: "Harry Potter and the Methods of Rationality",
author: "Yudkowsky, Eliezer",
pages: 750,
read: "Read"
},
{
title: "Go, Dog. Go!",
author: "Eastman, P.D.",
pages: 16,
read: "Partially Read"
}
];
library = sampleLibrary;
return library;
}
.shelf{ width: 350px; }
.book{ margin-top: 0.5em; padding: 0.5em; }
.delete-div{ text-align: right; } /* divs exist only to align buttons */
.delete-button{ border: 1px solid grey; border-radius: 0.3em; }
.hidden{ display: none; }
<div class="container">
<div class="buttons">
<button id="delete">Delete Books ➖</button>
<button class="button" id="add">Add Book ➕</button>
</div>
<div class="shelf"></div>
</div>