为图书查找器程序添加 JS 按钮单击处理程序函数,并在其中链接 javascript 函数

问题描述 投票:0回答:1

我基本上有一个帮助函数文件(helper.js),用于测试在script.js中实现的函数。项目呈现后,用户应该能够搜索图书列表中提供的图书(bookList.js),并且当找到该书时,它会显示在此 HTML (index.html) 中 文件加载到浏览器。我遇到的问题是在 script.js 文件中实现 searchBtnClickHandler 函数。我知道可以有匿名点击处理程序,但如何将定义的点击处理程序函数 (在 script.js 中定义为 searchBtnClickHandler) 连接到搜索按钮并链接之前的函数 (captureSearchValue、filterBooks 和 StructureBooksAsHtml) ? 我希望每个任务提供的注释中的说明能够为程序每个部分的用途提供更多参考。如果没有,请发表评论,以便我可以对其进行编辑以在此处添加更多说明。谢谢!

script.js

// Click handler for search button
const captureSearchValue = () => {
  const input = document.getElementById("search-bar").value;
  return input;
};

// Filter books based on search input and render filtered books to the DOM
const filterBooks = (input, books) => {
  const filteredBooks = [];
  let flattenedBooks = flattenObjectValuesIntoArray(books); // Call existing function
  for (let book = 0; book < books.length; book++) {
    // Search in the flattened books array, also make lowercase to include case insensitive results
    if (
      flattenedBooks[book]
        .map((e) => e.toLowerCase())
        .includes(input.toLowerCase())
    ) {
      filteredBooks.push(books[book]);
    }
  }
  return filteredBooks;

  // const filteredBooks = books.filter(book => book.tags.includes(input));
  // const filteredBooks = books.filter(book => book.tags.includes(input));
  // books.filter((book) => book.tags.includes(input));
};

// Empty the book list container, iterate over list of filtered books, return list of books formatted as HTML using the function in `helper.js`
const structureBooksAsHtml = (filteredBooks) => {
  const bookHTML = [];
  for (let book = 0; book < filteredBooks.length; book++) {
    bookHTML.push(structureBookAsHtml(filteredBooks[book]));
  }
  return bookHTML;
};

// Handler triggered when a user clickers the "Search" button. Chains previously defined functions together to filter books based on the search value, formats the books as HTML and renders them to the DOM
const searchBtnClickHandler = (event) => {
  captureSearchValue();
  filterBooks();
  structureBooksAsHtml();
};

// Grab search button from the DOM
searchBtn = document.getElementById("search-btn");
// Attach an event listener to the search button
searchBtn.addEventListener("click", () => {
  searchBtnClickHandler(books);
});

helper.js

/ Flatten object keys into an array so that we search the entire object by the input value
const flattenObjectValuesIntoArray = (arrOfObjs) => {
  let flattenedObj;
  const flattenedObjsArr = [];
  for (let obj = 0; obj < arrOfObjs.length; obj++) {
    const objValues = Object.values(arrOfObjs[obj]);
    flattenedObj = [...objValues.flat()]
    flattenedObjsArr.push(flattenedObj)
  }
  return flattenedObjsArr;
};

// Structure filtered books as HTML and return
const structureBookAsHtml = (book) => {
  const bookDiv = document.createElement("div");
  bookDiv.setAttribute('class', 'bookDiv');
  
  const bookTitle = document.createElement("h2");
  bookTitle.innerHTML = book.title;
  bookTitle.setAttribute('class', 'bookTitle');

  const bookAuthor = document.createElement("h3");
  bookAuthor.innerHTML = book.author;

  const bookTags = document.createElement("p");
  bookTags.innerHTML = book.tags.join(", ");

  bookDiv.append(bookTitle, bookAuthor, bookTags);
  
  return bookDiv;
};

const renderBooksToDom = (elements) => {
  const bookListContainer = document.querySelector("#bookList");
  bookListContainer.innerHTML = "";

  bookListContainer.append(...elements);
};

bookList.js

const books = [
  {
    title: "The City We Became",
    author: "N. K. Jemisin",
    tags: ["fantasy", "fiction", "afrofutursim", "science fiction", "sci-fi"]
  },
  {
    title: "The Catcher in the Rye",
    author: "J. D. Salinger",
    tags: ["fiction", "young adult", "YA", "realism", "coming of age", "classic"]
  },
  {
    title: "The Hundred Thousand Kingdoms",
    author: "N. K. Jemisin",
    tags: ["fantasy", "fiction", "adventure", "series"]
  },
  {
    title: "Sapiens: A Brief History of Humankind",
    author: "Yuval Noah Harari",
    tags: ["nonfiction", "history", "anthropology", "science", "sociology"]
  },
  {
    title: "Behave: The Biology of Humans at Our Best and Worst",
    author: "Robert M. Sapolsky",
    tags: ["nonfiction", "anthropology", "science", "sociology", "biology"]
  },
  {
    title: "The Parable of the Talents",
    author: "Octavia Butler", 
    tags: ["fiction", "dystopian", "science fiction"]
  },
  {
    title: "1984",
    author: "George Orwell", 
    tags: ["fiction", "dystopian", "science fiction", "classics", "adult"]
  },
  {
    title: "Remarkably Bright Creatures",
    author: "Shelby Van Pelt",
    tags: ["fiction", "mystery", "magical realism"]
  },
  {
    title: "Crying in H Mart",
    author: "Michelle Zauner",
    tags: ["memoir", "nonfiction", "autobiography"]
  },
  {
    title: "Wild: From Lost to Found on the Pacific Crest Trail",
    author: "Cheryl Strayed",
    tags: ["nonfiction", "memoir", "adventure", "travel"]
  }
]

index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="styles.css">
    <script src="bookList.js"></script>
    <script src="bookList.test.js"></script>
    <script src="helper.js"></script>
    <script src="script.js" defer></script>
  </head>
  <body>
    <h1>Book Finder</h1>
    <input id="search-bar" type="text" placeholder="Search for books by tags">
    <button class="btn" id="search-btn">Search</button>
    <div id="bookList">
      <!-- List of books will be rendered here -->
    </div>
  </body>
</html>
const searchBtnClickHandler = (event) => {
  captureSearchValue();
  filterBooks();
  structureBooksAsHtml();
};


在这行代码中,我尝试将函数链接到事件。我认为这是我的不足之处,但我愿意接受任何关于错误是否出在这部分代码或其他地方的建议。

javascript html event-handling
1个回答
0
投票

captureSearchValue()
这样的函数是普通函数,而不是
books
数组的方法。你应该用参数来调用它们,而不是
event.functionName()

// Handler triggered when a user clickers the "Search" button. Chains previously defined functions together to filter books based on the search value, formats the books as HTML and renders them to the DOM
const searchBtnClickHandler = (books) => {
  let input = captureSearchValue();
  let filtered = filterBooks(input, books);
  let array_of_objects = structureBooksAsHtml(filtered);
  renderBooksToDom(array_of_object.map(structureBookAsHtml));
};
© www.soinside.com 2019 - 2024. All rights reserved.