Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
505 views
in Technique[技术] by (71.8m points)

javascript - 使用keyup事件将更改动态应用于多个元素(Using keyup event to apply changes dynamically to multiple elements)

I am trying to build a basic JavaScript search functionality.(我正在尝试构建基本的JavaScript搜索功能。)

So I have a couple of divs and an input search field:(所以我有几个div和一个输入搜索字段:) <div class="notes"> <div class="firstNote">FIRST NOTE</div> <div class="secondNote">SECOND NOTE</div> <div class="thirdNote">THIRD NOTE</div> <div class="fourthNote">THIRDDD NOTE</div> <div class="fifthNote">THIRL NOTE</div> </div> <div class="search"> <input type="text" placeholder="Search..."> </div> The idea is that when the user types in the search box, it checks what they typed against the innerHTML values of the divs inside the parent notes div.(这个想法是,当用户在搜索框中键入内容时,它会根据父notes div中div的innerHTML值检查他们键入的内容。) While those values match, it should apply the searched class to those divs where the matching value is found.(当这些值匹配时,它应将searched到的类应用于找到匹配值的那些div。) And then hide all the other divs by giving them display:none .(然后通过给它们display:none隐藏所有其他div。) Once it stops finding a match, it should remove the searched class from all the divs and display them all again by giving them display:block .(一旦停止找到匹配项,就应该从所有div中删除searched类,并通过给它们display:block再次显示它们。) The trouble is that this works only for the first div it finds where there is a match.(麻烦的是,这仅适用于找到匹配项的第一个div。) I've created a couple of them starting with the letters 'THIR' for testing.(我创建了几个以“ THIR”开头的字母进行测试。) If I start typing 'thir', it only shows (ie applies the 'searched' class to) the first div whose text matches (the one with the thirdNote class), but not the other two even though they still also match.(如果我开始输入'thir',它将仅显示(即将'searched'类应用于)文本匹配的第一个div(与thirdNote类匹配的div),即使其他两个仍然匹配,也不会显示。) Here's the JS code:(这是JS代码:) const notes = document.querySelectorAll(".notes div"); const search = document.querySelector(".search input"); let count = 0; //detecting the number of times the user typed in the input field search.addEventListener("keyup", function(e){ let x = 1; //will use this to compare the values of the search box and the divs if(e.which === 16) //if the user presses Shift, don't do anything return; if(e.which !== 8) //if pressed anything but Backspace, increase the count count++; else if(e.which === 8 && count >= 1) { // otherwise decrease the count count--; } const textSearched = this.value; //what the user typed in the searchbox //if there is no text in the search box, remove the 'searched' class from all the divs, show all of them, and reset x back to 1 if(count === 0 || textSearched === ""){ notes.forEach(function(el){ if(el.style.display === "none") el.style.display = "block"; if(el.classList.contains("searched")) el.classList.remove("searched"); }); x = 1; } notes.forEach((body) => { //while the search box and the div text values match, and x is not greater than the div text length, add the 'searched' class and increment x while(textSearched.substring(0, x).toLowerCase() === body.innerHTML.substring(0, x).toLowerCase() && x <= body.innerHTML.length) { body.classList.add("searched"); x++; //if count is less than x, it means there is a match. So show all the matching divs, and hide all the other ones if(count < x) { notes.forEach((el) => { if(!el.classList.contains("searched")) el.style.display = "none"; else el.style.display = "block"; }); } // if count is equal or greater than x, it means no more matching, so show all the divs and remove the 'searched' class else { notes.forEach(function(el){ if(el.style.display === "none") el.style.display = "block"; if(el.classList.contains("searched")) el.classList.remove("searched"); }); } } }); }); Here is a working JS Fiddle: https://jsfiddle.net/tpxd5cqm/4/(这是一个有效的JS小提琴: https : //jsfiddle.net/tpxd5cqm/4/) Thanks!(谢谢!)   ask by Vlad77 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is what I'd do: toggle a class on the parent container when matching search elements are detected, and remove the class when there are no matches, or when the input is empty.(这就是我要做的:检测到匹配的搜索元素时在父容器上切换一个类,并在没有匹配项或输入为空时删除该类。)

When the parent class is active, highlight all .searched children, and hide all non- .searched children:(当父类处于活动状态时,突出显示所有.searched子级,并隐藏所有非.searched子级:) const container = document.querySelector('.notes'); const notes = [...container.children]; const input = document.querySelector('input'); input.addEventListener('keydown', () => { // Wait for the input field to contain its final value: setTimeout(checkInput); }); const checkInput = () => { const value = input.value.toLowerCase(); const matchingNotes = notes.filter(note => note.textContent.toLowerCase().includes(value)); if (!value || matchingNotes.length === 0) { container.classList.remove('searchActive'); return; } container.classList.add('searchActive'); for (const note of notes) { if (matchingNotes.includes(note)) { note.classList.add('searched'); } else { note.classList.remove('searched'); } } } .searchActive > .searched { background-color: yellow; } .searchActive > *:not(.searched) { display: none; } <div class="notes"> <div>FIRST NOTE</div> <div>SECOND NOTE</div> <div>THIRD NOTE</div> <div>THIRDDD NOTE</div> <div>THIRL NOTE</div> </div> <div> <input type="text" placeholder="Search..."> </div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...