#javascript #html
#javascript #HTML
Вопрос:
Я новичок в JS и следую руководству по списку фильтров W3CSchools, которое отлично работает при использовании getElementById, но, как я понимаю, идентификаторы должны быть уникальными для страницы.
Я изменил getElementsByClassName на getElementsByClassName, но, похоже, это не работает. Я хочу фильтровать результаты только в классе myUL, а не в классе otherUL, который можно найти в somedivclass3.
Я также хотел бы иметь возможность сопоставлять целые или частичные слова в любом порядке, например, «diff» будет соответствовать 3 из 4 li, а «different even» должно соответствовать 1 li.
JS:
<script>
function myFunction() {
// Declare variables
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementsByClassName("myUL");
li = ul.getElementsByTagName('li');
// Loop through all list items, and hide those who don't match the search query
for (i = 0; i < li.length; i ) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
</script>
HTML:
<input type="text" id="myInput" placeholder="Search for names..">
<input type="submit" onclick="myFunction()" value="Go">
<div class="somedivclass1">
<ul class="myUL">
<li>Text here</li>
<li>Different text here</li>
</ul>
</div>
<div class="somedivclass2">
<ul class="myUL">
<li>Even more different text here</li>
<li>Wildly different text here</li>
</ul>
</div>
<div class="somedivclass3">
<ul class="otherUL">
<li>Footer link 1</li>
<li>Footer link 2</li>
</ul>
</div>
Я бы хотел, чтобы это работало в соответствии с примером в школах W3C: https://www.w3schools.com/howto/howto_js_filter_lists.asp
Спасибо вам за всю помощь!
Комментарии:
1. У вас есть нулевые элементы с именем класса
myInput
.2. @CertainPerformance Извините, я обновил код. Я неправильно обновил не ту часть!
Ответ №1:
Я немного переписал вашу функцию, вы можете найти ее в виде фрагмента.
Первый цикл на ‘ul’ с правильным классом, затем второй цикл на ‘li’ С помощью jquery вы бы сделали это только в одной строке 🙂
function myFunction() {
// Declare variables
var input = document.getElementById('myInput');
var filter = input.value.toUpperCase();
//var li = document.getElementsByTagName('li');
var uls = document.getElementsByClassName("myUL");
for (var i = 0; i < uls.length; i ) {
var ul = uls[i];
var lis = ul.getElementsByTagName("li");
for (var j = 0; j < lis.length; j ) {
var li = lis[j];
var txtValue = li.textContent || li.innerText;
if (filtering(txtValue, filter)) {
li.style.display = "";
} else {
li.style.display = "none";
}
}
}
}
function filtering(text, searchString) {
const regexStr = '(?=.*' searchString.split(/,|s/).join(')(?=.*') ')';
const searchRegEx = new RegExp(regexStr, 'gi');
return text.match(searchRegEx) !== null;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<div class="somedivclass">
<ul class="myUL">
<li>Text here</li>
<li>Different text here</li>
</ul>
</div>
<div class="somedivclass2">
<ul class="myUL">
<li>Even more different text here</li>
<li>Widly different text here</li>
</ul>
</div>
Комментарии:
1. Спасибо @Julienrevaultd’A … Это работает, но на странице есть другие теги <li>, и они также отфильтровываются, поэтому я хотел ограничить его одним классом. Это также не позволяет вам изменять порядок слов в поиске, например, «разные», а «четный» не возвращает никаких результатов.
2. Может быть, вы могли бы отредактировать свой пост, потому что я не совсем понимаю, чего вы пытаетесь достичь 🙂
3. @Julienrevaultd’A … Я обновил сам вопрос с более подробной информацией. Спасибо вам за вашу помощь до сих пор!
4. @Julienrevaultd’A… Спасибо, Жюльен. Это определенно работает лучше, чем раньше! Единственная проблема заключается в том, что мне все еще нужно ограничить его «myUL», поскольку он также удаляет панировочные сухари и гиперссылки. Ранее я обновил код, добавив дополнительный div и другой класс UL. Не могли бы вы помочь?
5. @nr85: Проверьте последнюю версию, 1-й цикл на ul, затем цикл на li.. вам также следует взглянуть на jquery, это может помочь упростить код.
Ответ №2:
getElementsByClassName()
вернет массив элементов, потому что может быть много элементов с одним и тем же классом. Поэтому вместо этого попробуйте сначала перебрать все ul, а затем li:
for (i = 0; i < ul.length; i )
{
li = ul[i].getElementsByTagName('li');
for(j = 0; j< li.length; j )
{
a = li[j].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1)
{
li[j].style.display = "";
}
else
{
li[j].style.display = "none";
}
}
}
Комментарии:
1. Извините, я должен был выразиться яснее. Я бы хотел, чтобы он просматривал несколько разделов, которые он не выполняет. Я попробовал ваше предложение, но оно отображается только в первом div.
2. @nr85 вы должны перебирать все элементы, возвращаемые,
document.getElementsByClassName("myUL")
а не только первый элемент.3. @ErtanHasani Я попробовал код, который вы предоставили, но, к сожалению, я не смог заставить его работать.
4. @nr85 вы добавили
j
вvar
часть в начале?5. @ErtanHasani Да, я это сделал. Вот что у меня получилось: var input, filter, ul, li, a, i, j, txtValue;