问题描述
我有一个按钮“-”,当点击它时,它会在我的“书籍”的角落创建一个“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 有一个 toggle 方法,我们可以使用它来切换样式。如果您包含一个从 DOM 中删除元素的类(如 display: none
),这将成为一种简单的方法来隐藏/显示您的元素以响应用户操作。您可以在代码段的 toggleDeleteButtons
函数中了解其工作原理。
我对您的代码进行了一系列其他建议修改,您可以根据自己的喜好随意选择或离开。顺便说一句,上面的链接指向 MDN,这是一个很好的网站,可以搜索任何不熟悉的网络开发术语(例如,您只需在谷歌上搜索“MDN findIndex”即可了解 {{1} } 数组的方法。)
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,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,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; }