![](/img/trans.png)
[英]jquery “Filtering” a ul/li “tree” of data to show all children when a filter is met
[英]Show all children of li that is shown and that matches input with javascript
目前有一些 html 和 JS,我想用它來搜索修訂說明。 我的目標是,當 ul/li 的父項中的關鍵字等於輸入時,將顯示所有子項(如 css 中的 all * 選擇器)。
目的:如果一個 li 包含給定的輸入,則顯示該 li 的所有子項(例如示例 1、2、3) - 如果包含輸入的 li 旁邊的 li不包含輸入,則隱藏該輸入。
不同輸入和所需樣式 output 的示例:
示例 1
Input = keyword1 或 Input = Parent 1
父級 1 關鍵字 1 (style="display:block;")
子關鍵字 2 (style="display:block;")
“大”子關鍵字 3 (style="display:block;")
孩子 2 關鍵字 4 (style="display:block;")
“大”子關鍵字 5 (style="display:block;")
父 2 關鍵字 6 (style="display:none;")
孩子 2 關鍵字 7 (style="display:none;")
“大”子關鍵字 8 (style="display:none;")
孩子 3 關鍵字 9 (style="display:none;")
“大”子關鍵字 10 (style="display:none;")
示例 2
輸入 = 關鍵字 2 或輸入 = 關鍵字 3
父級 1 關鍵字 1 (style="display:block;")
子關鍵字 2 (style="display:block;")
“大”子關鍵字 3 (style="display:block;")
孩子 2 關鍵字 4 (style="display:none;")
“大”子關鍵字 5 (style="display:none;")
父 2 關鍵字 6 (style="display:none;")
孩子 2 關鍵字 7 (style="display:none;")
“大”子關鍵字 8 (style="display:none;")
孩子 3 關鍵字 9 (style="display:none;")
“大”子關鍵字 10 (style="display:none;")
示例 3
輸入 = 關鍵字 4 或輸入 = 關鍵字 5
父級 1 關鍵字 1 (style="display:block;")
子關鍵字 2 (style="display:none;")
“大”子關鍵字 3 (style="display:none;")
孩子 2 關鍵字 4 (style="display:block;")
“大”子關鍵字 5 (style="display:block;")
父 2 關鍵字 6 (style="display:none;")
孩子 2 關鍵字 7 (style="display:none;")
“大”子關鍵字 8 (style="display:none;")
孩子 3 關鍵字 9 (style="display:none;")
“大”子關鍵字 10 (style="display:none;")
當前,當輸入輸入時,function 僅顯示匹配的確切 li - 我希望顯示所有子項。 又怎樣? 謝謝。 請參閱下面的代碼。
function searchTitle() { var input, filter, ul, li, a, i; input = document.getElementById("myInput"); filter = input.value.toUpperCase(); window.status = filter; ul = document.getElementById("List"); li = ul.getElementsByTagName("li"); for (i = 0; i < li.length; i++) { a = li[i]; if (a.textContent.toUpperCase().indexOf(filter) > -1) { a.style.display = ""; } else { a.style.display = "none"; } } }
<,DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width; initial-scale=1"> <body> <input type="text" id="myInput" onkeyup="searchTitle()" placeholder="Search through notes" title="Type in a keyword"> <ul id="List"> <li> Parent 1 keyword1 <ul> <li> Child keyword2 <ul> <li>"Grand" Child keyword3</li> </ul> </li> <li> Child 2 keyword4 <ul> <li>"Grand" Child keyword5</li> </ul> </li> </ul> </li> <li> Parent 2 keyword6 <ul> <li> Child 2 keyword7 <ul> <li>"Grand" Child keyword8</li> </ul> </li> <li> Child 3 keyword9 <ul> <li>"Grand" Child keyword10</li> </ul> </li> </ul> </li> </ul> </body> </html>
const $input = document.querySelector("#myInput");
$input.addEventListener("input", (e) => {
const query = e.target.value;
const $ul = document.querySelector("ul");
const $lis = $ul.querySelectorAll("li");
const $matchedLis = [...$lis].filter(($li) => $li.textContent.match(query));
[...$lis].forEach(($li) => $li.classList.add("hide"));
[...$matchedLis].forEach(($li) => {
$li.classList.remove("hide");
[...$li.querySelectorAll("li")].map(($li) => $li.classList.remove("hide"));
});
});
https://jsfiddle.net/3bh2paow/
它的作用:在輸入時觸發事件。 [不是按鍵] 為了可讀性,我使用以$
開頭的變量,它們表示 dom 元素。 我通過將 hide class 添加到元素來隱藏元素。 [不是內聯 JS]
代碼步驟: 過濾所有匹配查詢字符串(輸入值)的列表 隱藏所有列表 取消隱藏(通過刪除隱藏類)被過濾的元素。 取消隱藏上一步的所有子元素。
您的 function 正在設置display: none
到所有與搜索關鍵字不匹配的li
。 但是由於您使用.textContent
,父母不受影響(無論如何他們匹配)。
所以現在對於孩子們,我使用遞歸 function 循環遍歷匹配的所有子節點,直到沒有子節點,如果它是LI
元素,則在它們上設置display: ""
。
我使用setTimeout
來確保遞歸在searchTitle
循環完成時發生。 注意let a
而不是var
。 那就是確保傳遞匹配的元素。
function searchTitle() { var input, filter, ul, li, i; input = document.getElementById("myInput"); filter = input.value.toUpperCase(); window.status = filter; ul = document.getElementById("List"); li = ul.getElementsByTagName("li"); for (i = 0; i < li.length; i++) { let a = li[i]; if (a.textContent.toUpperCase().indexOf(filter) > -1) { a.style.display = ""; setTimeout(()=>displayChilds(a),1) // Call the recusrsive function } else { a.style.display = "none"; } } } // Recursive function called from a matching element function displayChilds(el){ if(el.hasChildNodes){ el.childNodes.forEach(child => { if(child.tagName == "LI"){ child.style.display = "" } displayChilds(child) // Recusion occurs here }) } }
<,DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width; initial-scale=1"> <body> <input type="text" id="myInput" onkeyup="searchTitle()" placeholder="Search through notes" title="Type in a keyword"> <ul id="List"> <li> Parent 1 keyword1 <ul> <li> Child keyword2 <ul> <li>"Grand" Child keyword3</li> </ul> </li> </ul> </li> <li> Parent 2 keyword4 <ul> <li> Child keyword5 <ul> <li>"Grand" Child keyword6</li> </ul> </li> </ul> </li> </ul> </body> </html>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.