Как на JS реализовать фильтрацию списка элементов в реальном времени при вводе текста пользователем?

Фильтрация списка элементов в реальном времени — одна из самых востребованных задач во фронтенд-разработке. Она позволяет пользователю мгновенно находить нужный элемент без перезагрузки страницы. Рассмотрим несколько подходов к реализации.

**Базовый подход с использованием событий input**

Самый простой способ — повесить обработчик события `input` на текстовое поле и при каждом изменении фильтровать элементы списка.

HTML-разметка:
html

  • Яблоко
  • Банан
  • Апельсин
  • Груша
  • Манго

JavaScript:
javascript
const input = document.getElementById(‘search’);
const items = document.querySelectorAll(‘#list li’);

input.addEventListener(‘input’, function() {
const query = this.value.toLowerCase().trim();

items.forEach(item => {
const text = item.textContent.toLowerCase();
item.style.display = text.includes(query) ? » : ‘none’;
});
});

Здесь мы получаем все элементы `

  • `, и при каждом вводе скрываем те, которые не содержат введённую подстроку.

    **Фильтрация массива данных с перерисовкой DOM**

    Если список генерируется динамически из массива данных, лучше хранить исходные данные отдельно и перерисовывать список при каждом запросе:

    javascript
    const fruits = [‘Яблоко’, ‘Банан’, ‘Апельсин’, ‘Груша’, ‘Манго’];
    const list = document.getElementById(‘list’);
    const input = document.getElementById(‘search’);

    function renderList(items) {
    list.innerHTML = items.map(item => `

  • ${item}
  • `).join(»);
    }

    input.addEventListener(‘input’, function() {
    const query = this.value.toLowerCase().trim();
    const filtered = fruits.filter(item => item.toLowerCase().includes(query));
    renderList(filtered);
    });

    renderList(fruits); // начальный рендер

    **Оптимизация с debounce**

    При большом количестве элементов или сложной логике рекомендуется использовать debounce — задержку перед выполнением функции, чтобы не вызывать её на каждое нажатие клавиши:

    javascript
    function debounce(fn, delay) {
    let timer;
    return function(…args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
    };
    }

    input.addEventListener(‘input’, debounce(function() {
    const query = this.value.toLowerCase().trim();
    const filtered = fruits.filter(item => item.toLowerCase().includes(query));
    renderList(filtered);
    }, 300));

    **Дополнительные улучшения**

    — Подсветка совпадений: оборачивайте найденную подстроку в `` для визуального выделения.
    — Регистронезависимость: всегда приводите строки к нижнему регистру через `.toLowerCase()`.
    — Поддержка кириллицы и латиницы: метод `includes()` работает с любыми символами Unicode.
    — Доступность: добавьте атрибут `aria-live=»polite»` к списку, чтобы скринридеры сообщали об изменениях.

    Таким образом, фильтрация списка в реальном времени реализуется несколькими строками кода и не требует сторонних библиотек.


    Задайте вопрос нейросети

    Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.