Реализовать поиск по скрытому списку ul -> li

Рейтинг: 0Ответов: 1Опубликовано: 22.02.2023

Помогите пожалуйста. Покурил форум, слепил из двух решений одно, но оно, естественно, оказалось не рабочим. С js даже не на Вы.

Коротко, что хочу сделать: Список. В нем дивы, раскрывающиеся и закрывающиеся по клику мышкой(работает), в этих дивах ссылки (есть). -> Поиск по вложенному списку. То-есть вот по прямым названиям ссылок поиск работает, по спрятанным div`ы - нет. Это нужно исправить. И третье, не менее важное, было бы очень круто, чтобы когда название вводится в поиск и такое значение находится - див открывался и показывал это название.

Пример: в точности так работает поиск который вдохновляет - https://www.exist.ru/Catalog/Global/Cars/Ford/9751/3690003C

Мой код

<input type="text" id="inputSearch" placeholder="Search.." title="Type in a category">
<ul id="list">
    <li><a href="#">Детали подвески</a>
        <div id="mydiv" style="display:none;">
            <ul class="rem">
                <li><a href="#">папа</a></li>
                <li><a href="#">мама</a></li>
                <li><a href="#">я</a></li>
            </ul>
        </div>
    </li>
    <li><a href="#">Детали подвески</a>
        <div id="mydiv" style="display:none;">
            <ul class="rem">
                <li><a href="#">жираф</a></li>
                <li><a href="#">рыба</a></li>
                <li><a href="#">путин</a></li>
            </ul>
        </div>
    </li>
    <li><a href="#">CSS</a></li>
    <li><a href="#">Node.js</a></li>
</ul>
<script>
function search() {
    let input = document.getElementById("inputSearch");
    let filter = input.value.toUpperCase();
    let ul = document.getElementById("list");
    let li = ul.getElementsByTagName("li");
    
    // Перебирайте все элементы списка и скрывайте те, которые не соответствуют поисковому запросу
    for (let i = 0; i < li.length; i++) {
    let a = li[i].getElementsByTagName("a")[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
    li[i].style.display = "";
    } else {
    li[i].style.display = "none";
    }
    }
    }
    document.addEventListener('keyup', search);
    function viewdiv(id){
    var el=document.getElementById(id);
    if(el.style.display=="block"){
    el.style.display="none";
    } else {
    el.style.display="block";
    }
    }
</script>

Ответы

▲ 1

Если следовать логике работы поиска по приведённой в вопросе ссылке, то желательно немного поправить разметку и переписать скрипт:

let categoriesAll = [...categories.children];
/* Развернуть/свернуть категории */
function fShowHide(ev) {
  if (!ev.target.classList.contains('category')) return;
  ev.target.nextElementSibling.classList.toggle('visible');
}
categories.addEventListener('click', fShowHide);
/* Основная функция поиска */
function fSearch() {
  fMark(categories);
  let searchText = new RegExp(`(${inputSearch.value})`, 'giu');
  categoriesAll.forEach((cat) => {
    if (searchText.test(cat.textContent)) {
      let category = cat.querySelector('.category');
      fMark(category, inputSearch.value, searchText);
      let itemsAll = cat.querySelectorAll('.items > li');
      itemsAll.forEach((el) => {
        if (searchText.test(el.textContent)) {
          fMark(el.children[0], inputSearch.value, searchText);
          el.classList.toggle('hide', false);
        } else {
          el.classList.toggle('hide', true);
        }
      });
      cat.querySelector('.items').classList.toggle('visible', (inputSearch.value != ''));
      cat.classList.toggle('hide', false);
    } else {
      cat.classList.toggle('hide', true);
    }
  });
}
inputSearch.addEventListener('input', fSearch);
/* Подсветка совпадений */
function fMark(obj, txt, rexp) {
  if (txt) {
    obj.innerHTML = obj.textContent.replace(rexp, `<mark>$1</mark>`);
  } else {
    obj.querySelectorAll('mark').forEach((mark) => {
      mark.replaceWith(mark.textContent);
    });
  }
}
categories > li { margin-bottom: 0.5em; }
.category { font: bold 14px/1.5em sans-serif; }
.items { font: 14px/1.5em sans-serif; }
.items:not(.visible) { display: none; }
.hide { display: none !important; }
mark { background-color: #fd0 !important; }
<input type="search" id="inputSearch" placeholder="Поиск..." title="Type in a category">
<ul id="categories">
  <li>
    <div class="category">Инструменты</div>
    <ul class="items">
      <li><a href="#">Паяльная лампа</a></li>
      <li><a href="#">Ключ рожковый</a></li>
      <li><a href="#">Патрон для шуруповёрта</a></li>
    </ul>
  </li>
  <li>
    <div class="category">Освещение</div>
    <ul class="items">
      <li><a href="#">Светодиодный светильник</a></li>
      <li><a href="#">Галогенный светильник</a></li>
      <li><a href="#">Влагозащищенный патрон</a></li>
    </ul>
  </li>
  <li>
    <div class="category">Краска</div>
    <ul class="items">
      <li><a href="#">Люминесцентная</a></li>
      <li><a href="#">Флуоресцентная</a></li>
      <li><a href="#">Световозвращающая</a></li>
    </ul>
  </li>
  <li>
    <div class="category">Разное</div>
    <ul class="items">
      <li><a href="#">Набор шурупов по дереву</a></li>
      <li><a href="#">Заготовка для ключа</a></li>
      <li><a href="#">Жилет световозвращающий</a></li>
    </ul>
  </li>
</ul>