求助:单搜索框实现按文件名/多类别统一搜索的JS方案
问题描述
我正在开发一个文档展示网页,需要实现按文件名和类别搜索的功能。已经设置了类别下拉框和搜索输入框,但当前两个事件监听器复用同一个search输入框,只能单独实现文件名或单一类别搜索,无法统一处理所有类别,希望用同一个函数实现全类别搜索的JS或jQuery方案。
现有代码
HTML结构
<section id="top1"> <div class="top-left"> <span><i class="mdi mdi-cloud-search"></i></span> <div class="dropDown"> <select id="selectbox1"> <option value="file_name" class="file_name">File Name</option> <option value="probation" class="probation">Probation Review</option> <option value="signed" class="signed">Signed Policies</option> <option value="sick" class="sick">Sick Notes</option> <option value="family" class="family">Family Responsibility Leave</option> <option value="private" class="private">Private</option> <option value="warnings" class="warnings">Warnings</option> <option value="assets" class="assets">Assets</option> <option value="certificates" class="certificates">Certificates</option> </select> </div> <div class="search"> <input id="search" type="text" placeholder="search" > </div> </div> <div class="upload"> <button>Upload Files</button> </div> </section> <!-- #1documents row --> <section class="reuse"> <h3>Probation Reviews</h3> <div class="documents first-section" id="probation-review"></div> </section> <!-- #2documents row --> <section class="reuse "> <h3>Signed Policies</h3> <div class="documents first-section" id="signed-policies"></div> </section> <!-- #3documents row --> <section class="reuse"> <h3>Sick Notes</h3> <div class="documents first-section" id="sick-notes"></div> </section>
文档渲染JS示例
/*Sick Notes*/ const sick_note_arry = [ { path: "https://documentcloud.adobe.com/view-sdk-demo/PDFs/Bodea Brochure.pdf", title: "Clinics", sub_title: "1 Jan 2022 10:15" }, { path: "assets/textFiles/sample3.txt", title: "Doctors", sub_title: "1 Jan 2022 10:15" }, { path: "https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210101201653/PDF.pdf", title: "Dr Appointment", sub_title: "1 Jan 2022 10:15" }, ] const mainCard = document.getElementById("sick-notes"); for (var i = 0; i < sick_note_arry.length; i++) { const newCard = document.createElement("div"); newCard.classList.add("myDocs"); mainCard.classList.add("first-section"); cardHtml = ` <div class="innerDoc"> <iframe src="${sick_note_arry[i].path}" alt="" width='200px' height='200px' ></iframe> <h5>${sick_note_arry[i].title}</h5> <h6>${sick_note_arry[i].sub_title}</h6> </div> `; mainCard.appendChild(newCard); newCard.innerHTML = cardHtml; } /*End Of Sick Notes*/
现有搜索监听器
// 按文件名搜索 const get_input = document.getElementById("search"); const inner_div = document.getElementsByClassName("myDocs"); get_input.addEventListener("keyup", (event)=>{ const valueKey = event.target.value; const search_items = document.querySelectorAll(".myDocs h5"); for (var i = 0; i < search_items.length; i++) { const myElements = search_items[i].innerHTML; if (myElements.trim().toLowerCase().indexOf(valueKey.trim().toLowerCase()) > -1) { inner_div[i].style.display = "block"; } else { inner_div[i].style.display = "none"; } } }) // 按单一类别搜索 const inner_diver = document.querySelectorAll("#probation-review .myDocs"); get_input.addEventListener("keyup", (e) => { const valueKey = e.target.value; for (var i = 0; i < inner_diver.length; i++) { const myElements = inner_diver[i].innerHTML; if (myElements.trim().toLowerCase().indexOf(valueKey.trim().toLowerCase()) > -1) { inner_diver[i].style.display = "block"; } else { inner_diver[i].style.display = "none"; } } })
解决方案
核心思路
根据下拉框选中的选项,动态切换搜索范围和匹配规则:
- 选中
file_name时,搜索所有文档的标题 - 选中具体类别时,仅搜索该类别下的文档标题
原生JS实现
1. 先统一管理文档数据(推荐优化)
把所有类别文档整合到一个数组,后续维护更方便:
// 整合所有文档,每个条目带category标记 const allDocuments = [ // 试用期评审 { category: "probation", path: "...", title: "Probation Doc 1", sub_title: "..." }, // 已签署政策 { category: "signed", path: "...", title: "Policy Doc 1", sub_title: "..." }, // 病假条 { category: "sick", path: "https://documentcloud.adobe.com/view-sdk-demo/PDFs/Bodea Brochure.pdf", title: "Clinics", sub_title: "1 Jan 2022 10:15" }, { category: "sick", path: "assets/textFiles/sample3.txt", title: "Doctors", sub_title: "1 Jan 2022 10:15" }, { category: "sick", path: "https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210101201653/PDF.pdf", title: "Dr Appointment", sub_title: "1 Jan 2022 10:15" }, // 其他类别文档依次补充 ]; // 统一渲染函数 function renderDocuments() { // 清空所有容器 document.querySelectorAll(".documents").forEach(container => container.innerHTML = ""); allDocuments.forEach(doc => { // 根据category匹配容器ID(可统一命名规则,比如都用${category}-docs) const containerId = `${doc.category}-review` || `${doc.category}-policies` || `${doc.category}-notes`; const mainCard = document.getElementById(containerId); if (!mainCard) return; const newCard = document.createElement("div"); newCard.classList.add("myDocs"); // 给卡片加category数据属性,方便后续筛选 newCard.dataset.category = doc.category; const cardHtml = ` <div class="innerDoc"> <iframe src="${doc.path}" alt="" width='200px' height='200px'></iframe> <h5>${doc.title}</h5> <h6>${doc.sub_title}</h6> </div> `; newCard.innerHTML = cardHtml; mainCard.appendChild(newCard); }); } // 页面加载完成后渲染 window.addEventListener("DOMContentLoaded", renderDocuments);
2. 统一搜索函数
const searchInput = document.getElementById("search"); const selectBox = document.getElementById("selectbox1"); function handleSearch() { const searchValue = searchInput.value.trim().toLowerCase(); const selectedCategory = selectBox.value; const allDocCards = document.querySelectorAll(".myDocs"); allDocCards.forEach(card => { const docTitle = card.querySelector("h5").textContent.trim().toLowerCase(); const docCategory = card.dataset.category; let shouldShow = false; if (selectedCategory === "file_name") { // 按文件名搜索:标题匹配则显示 shouldShow = docTitle.includes(searchValue); } else { // 按类别搜索:类别匹配且标题匹配才显示 shouldShow = docCategory === selectedCategory && docTitle.includes(searchValue); } card.style.display = shouldShow ? "block" : "none"; // 优化:如果类别下无匹配文档,隐藏整个类别区块 const section = card.closest(".reuse"); const hasVisibleDocs = section.querySelectorAll(".myDocs[style='display: block;']").length > 0; section.style.display = hasVisibleDocs ? "block" : "none"; }); // 搜索框为空时,恢复显示所有内容 if (searchValue === "") { document.querySelectorAll(".reuse").forEach(section => section.style.display = "block"); allDocCards.forEach(card => card.style.display = "block"); } } // 绑定触发事件:输入框输入、下拉框切换都执行搜索 searchInput.addEventListener("keyup", handleSearch); selectBox.addEventListener("change", handleSearch);
jQuery实现(更简洁)
$(function() { const $searchInput = $("#search"); const $selectBox = $("#selectbox1"); function handleSearch() { const searchValue = $searchInput.val().trim().toLowerCase(); const selectedCategory = $selectBox.val(); $(".myDocs").each(function() { const $card = $(this); const docTitle = $card.find("h5").text().trim().toLowerCase(); const docCategory = $card.data("category"); let shouldShow = false; if (selectedCategory === "file_name") { shouldShow = docTitle.includes(searchValue); } else { shouldShow = docCategory === selectedCategory && docTitle.includes(searchValue); } $card.toggle(shouldShow); // 处理类别区块显示隐藏 const $section = $card.closest(".reuse"); const hasVisible = $section.find(".myDocs:visible").length > 0; $section.toggle(hasVisible); }); if (searchValue === "") { $(".reuse, .myDocs").show(); } } $searchInput.on("keyup", handleSearch); $selectBox.on("change", handleSearch); });
内容的提问来源于stack exchange,提问作者Chamano
相关产品推荐
相关产品推荐

