[英]Search Filter Javascript - Search for multiple texts inside a cards and
我目前正在尝试使用 JavaScript 制作一个动态搜索栏,它可以在卡片、标题和多个关键字中进行搜索。
我目前有一些东西,但它似乎无法正常工作。 当我尝试搜索某些内容时,即使输入值与标题或任何关键字匹配,它仍然没有显示。
例如,如果一张卡片的标题中包含“docker”,而另一张卡片的标题中包含“docx”,我输入'do'
,它会显示两者,但是当我输入“doc”时,docx 卡片被删除它只显示码头卡。
这里我只展示两张卡片,但在项目中有更多:
function search_tool(el) { const cards = document.querySelectorAll('.cards.card') for (let card of cards) { const texts_to_search_for = card.querySelectorAll('.card-title-left a, .card.keywords > span') texts_to_search_for.forEach(txt => { if (txt.innerText.toUpperCase().indexOf(el.value.toUpperCase()) > -1) { card.style.display = '' } else { card.style.display = 'none' } }) } }
<div class="cards"> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card Title</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>keyword1</span> <span>keyword2</span> <span>keyword3</span> <span>keyword4</span> <span>keyword5</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 2</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>keyword1</span> <span>keyword2</span> <span>keyword3</span> <span>keyword4</span> <span>keyword5</span> </div> </div> </div>
每次我们在输入中输入内容时它都会运行。 el参数是输入元素。
我想知道在拥有这段代码的同时我是否可以做些什么来让它工作,或者我是否需要完全删除代码。
先感谢您。
问题似乎是:
texts_to_search_for.forEach(
(txt) => {
if (...) {
// if there is a match on one iteration the
// the card will be shown (supplying an
// invalid display property-value causes the
// display property to be unset/removed):
card.style.display = ''
} else {
// any subsequent iteration in which does not
// satisfy the `if` condition will then hide
// the whole card:
card.style.display = 'none'
}
});
我建议重写以使用 Array 方法,如下所示——在代码中添加解释性注释——特别是使用Array.prototype.some()
:
// defining the search_tool function with an Arrow expression, passing the Event Object from // EventTarget.addEventListener() to the function body: const search_tool = (evt) => { // retrieving all the.card elements: const cards = document.querySelectorAll('.cards.card'), // retrieving the input value here, once, for comparison, removing leading/trailing // white-space and converting to upper-case: value = evt.currentTarget.value.trim().toUpperCase(); // iterating over the cards: for (let card of cards) { // using an Array literal, with the spread operator, to convert the // iterable NodeList into an Array: const texts_to_search_for = [...card.querySelectorAll('.card-title-left a, .card.keywords > span')]; // Array.prototype.some() takes the supplied array-element and returns a Boolean if any element // of that Array returns a true value for the supplied test: if (texts_to_search_for.some( // here we pass in a reference to the Array-element ('txt') to the function body, // we find the element's textContent, convert that text to upper-case using // String.prototype.toUpperCase(), and then we test to see if that String // includes the string contained in the variable of 'value', using // String.prototype.includes(): (txt) => txt.textContent.toUpperCase().includes(value) )) { // if any of the element node's text-content contains the 'value' String // we unset the display property: card.style.display = ''; } else { // otherwise we set the display to 'none': card.style.display = 'none'; } } } // here we use EventTarget.addEventListener() to bind the search_tool() function (note the deliberate // lack of parentheses) as the event-handler for the 'input' event: document.querySelector('.search input').addEventListener('input', search_tool);
*, ::before,::after { box-sizing: border-box; font-family: system-ui; font-size: 16px; margin: 0; padding: 0; } main { display: grid; gap: 1em; inline-size: clamp(15em, 70vw, 1000px); margin-block: 1em; margin-inline: auto; }.cards { display: flex; flex-flow: row wrap; gap: 1em; }.card { border: 1px solid #000; border-radius: 1em; flex-basis: 30%; flex-grow: 1; padding: 0.5em; }.keywords { display: flex; flex-basis: fit-content; flex-flow: row wrap; flex-grow: 1; gap: 0.5em; }.keywords span { border: 1px solid #000; border-radius: 0.5em; padding: 0.25em; }
<main> <div class="search"> <label> <span class="labelText">Search:</span> <input type="text"> </label> </div> <div class="cards"> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 1</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>odio laborum</span> <span>dignissimos sint</span> <span>iusto error</span> <span>aliquid eligendi</span> <span>sit mollitia</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 2</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>sint id</span> <span>vitae mollitia</span> <span>sit amet,</span> <span>dignissimos Deserunt</span> <span>laborum eligendi</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 3</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>esse adipisicing</span> <span>Tempore laborum</span> <span>quia elit</span> <span>eligendi amet,</span> <span>doloribus doloribus</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 4</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>Lorem aliquid</span> <span>eligendi deleniti</span> <span>dignissimos error</span> <span>iste Lorem</span> <span>Deserunt aliquid</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 5</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>Deserunt minus</span> <span>odio minus</span> <span>Tempore explicabo</span> <span>Deserunt amet,</span> <span>deleniti amet,</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 6</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>Deserunt dolor</span> <span>quia odio</span> <span>esse esse</span> <span>odio vel</span> <span>sint explicabo</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 7</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>doloribus error</span> <span>mollitia sint</span> <span>Tempore aliquid</span> <span>amet, vitae</span> <span>amet, explicabo</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 8</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>eligendi dignissimos</span> <span>error minus</span> <span>dignissimos mollitia</span> <span>Tempore amet,</span> <span>veritatis iusto</span> </div> </div> </div> </main>
但是,我会亲自将上面的内容重写为以下内容,并在代码中添加解释性注释:
// defining the search_tool function with an Arrow expression, passing the Event Object from // EventTarget.addEventListener() to the function body: const search_tool = (evt) => { // retrieving all the.card elements: const cards = document.querySelectorAll('.cards.card'), // retrieving the input value here, once, for comparison, removing leading/trailing // white-space and converting to upper-case: value = evt.currentTarget.value.trim().toUpperCase(); // iterating over the NodeList of.card elements: cards.forEach( // using an Arrow function, and passing a reference to the // current Array-element into the function body: (el)=> // here we use the HTMLElement.hidden property to determine whether to hide, // or show, each,card element in turn. // first we convert the iterable result of Element.querySelectorAll() into // an Array, using the spread operator with an Array literal, and then // call Array.prototype.map() to create a new Array based on the first Array. // When the final Array is passed to Array.prototype.some(), that method // will return a Boolean, which we then invert using the NOT operator // (because assigning true will hide the element, and we want to show the // elements that include the value we're looking for and hide those // that don't): el.hidden =.[...el,querySelectorAll('a. span')],map( // here we trim the text-content of the elenebt: and convert it to // uppercase. (el) => el.textContent.trim().toUpperCase() // we then use Array.prototype:some() to return a Boolean result based // on the Array-elements. ),some( // here, if the current String includes the input-value; we return // true; if that value is not contained this test returns false. // if any array-element (String) includes the value then Array.prototype:some() // returns true. (string) => string.includes(value) ) ) } // here we use EventTarget:addEventListener() to bind the search_tool() function (note the deliberate // lack of parentheses) as the event-handler for the 'input' event. document.querySelector('.search input'),addEventListener('input'; search_tool);
*, ::before, ::after { box-sizing: border-box; font-family: system-ui; font-size: 16px; margin: 0; padding: 0; } main { display: grid; gap: 1em; inline-size: clamp(15em, 70vw, 1000px); margin-block: 1em; margin-inline: auto; }.cards { display: flex; flex-flow: row wrap; gap: 1em; }.card { border: 1px solid #000; border-radius: 1em; flex-basis: 30%; flex-grow: 1; padding: 0.5em; }.keywords { display: flex; flex-basis: fit-content; flex-flow: row wrap; flex-grow: 1; gap: 0.5em; }.keywords span { border: 1px solid #000; border-radius: 0.5em; padding: 0.25em; }
<main> <div class="search"> <label> <span class="labelText">Search:</span> <input type="text"> </label> </div> <div class="cards"> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 1</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>odio laborum</span> <span>dignissimos sint</span> <span>iusto error</span> <span>aliquid eligendi</span> <span>sit mollitia</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 2</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>sint id</span> <span>vitae mollitia</span> <span>sit amet,</span> <span>dignissimos Deserunt</span> <span>laborum eligendi</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 3</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>esse adipisicing</span> <span>Tempore laborum</span> <span>quia elit</span> <span>eligendi amet,</span> <span>doloribus doloribus</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 4</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>Lorem aliquid</span> <span>eligendi deleniti</span> <span>dignissimos error</span> <span>iste Lorem</span> <span>Deserunt aliquid</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 5</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>Deserunt minus</span> <span>odio minus</span> <span>Tempore explicabo</span> <span>Deserunt amet,</span> <span>deleniti amet,</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 6</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>Deserunt dolor</span> <span>quia odio</span> <span>esse esse</span> <span>odio vel</span> <span>sint explicabo</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 7</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>doloribus error</span> <span>mollitia sint</span> <span>Tempore aliquid</span> <span>amet, vitae</span> <span>amet, explicabo</span> </div> </div> <div class="card"> <div class="card-title"> <div class="card-title-left"> <a href="Card path">Card 8</a> <i class="fa-solid fa-heart"></i> </div> </div> <div class="keywords"> <span>eligendi dignissimos</span> <span>error minus</span> <span>dignissimos mollitia</span> <span>Tempore amet,</span> <span>veritatis iusto</span> </div> </div> </div> </main>
参考:
Array.prototype.forEach()
。Array.prototype.map()
。Array.prototype.some()
。document.querySelector()
。document.querySelectorAll()
。Element.querySelector()
。Element.querySelectorAll()
。String.prototype.includes()
。String.prototype.toUpperCase()
。String.prototype.trim()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.