Как на 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 => `
`).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»` к списку, чтобы скринридеры сообщали об изменениях.
Таким образом, фильтрация списка в реальном времени реализуется несколькими строками кода и не требует сторонних библиотек.
