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>