Для работы с библиотекой Isotope необходимо подключить её к проекту через CDN или локально. Базовая структура подключения выглядит следующим образом:
Инициализация Isotope происходит на контейнере элементов, который содержит все карточки или блоки, подлежащие фильтрации:
var grid = document.querySelector('.grid');
var iso = new Isotope(grid, {
itemSelector: '.grid-item',
layoutMode: 'fitRows',
getSortData: {
name: '.name',
category: '[data-category]'
}
});
Здесь itemSelector определяет элементы, которые будут
участвовать в фильтрации, а layoutMode задаёт тип
раскладки. Атрибут getSortData позволяет сортировать
элементы по заданным критериям, например, по имени или категории.
Фильтрация на стороне сервера предполагает, что клиент получает не весь массив данных сразу, а только необходимый под запрос набор. В отличие от клиентской фильтрации, где все элементы уже находятся на странице, серверная фильтрация уменьшает нагрузку на браузер и ускоряет работу с большим объёмом данных.
Основные этапы реализации:
appended
или reloadItems.Пример запроса через fetch:
function fetchFilteredData(filter) {
fetch(`/api/items?category=${filter}`)
.then(response => response.json())
.then(data => {
updateIsotopeGrid(data);
});
}
После получения массива элементов от сервера необходимо правильно интегрировать их в Isotope.
Удаление старых элементов:
var items = iso.getItemElements();
iso.remove(items);
iso.layout();
Добавление новых элементов:
function updateIsotopeGrid(data) {
var fragment = document.createDocumentFragment();
data.forEach(item => {
var div = document.createElement('div');
div.className = 'grid-item';
div.setAttribute('data-category', item.category);
div.innerHTML = `${item.name}
${item.description}
`;
fragment.appendChild(div);
});
grid.appendChild(fragment);
iso.appended(fragment.children);
iso.layout();
}
Метод appended добавляет новые элементы и интегрирует их
в существующую раскладку с анимацией, а layout обеспечивает
корректное расположение всех блоков.
Isotope поддерживает фильтрацию по нескольким атрибутам с использованием CSS-селекторов. Для серверной фильтрации важно передавать на сервер все активные критерии, а на клиенте только отображать результаты.
Пример передачи нескольких фильтров:
var filters = {
category: 'electronics',
priceRange: '100-500',
inStock: true
};
fetch(`/api/items?category=${filters.category}&priceRange=${filters.priceRange}&inStock=${filters.inStock}`)
.then(response => response.json())
.then(data => updateIsotopeGrid(data));
На сервере происходит комбинированная фильтрация:
filtered_items = all_items
if category:
filtered_items = [item for item in filtered_items if item.category == category]
if price_range:
min_price, max_price = map(int, price_range.split('-'))
filtered_items = [item for item in filtered_items if min_price <= item.price <= max_price]
if in_stock:
filtered_items = [item for item in filtered_items if item.in_stock]
Isotope позволяет плавно анимировать появление и исчезновение элементов при фильтрации. Для серверной фильтрации это реализуется через последовательность удаления старых элементов и добавления новых:
function applyFilter(filter) {
fetchFilteredData(filter);
}
После получения новых данных сетка автоматически перестраивается с анимацией, создавая ощущение непрерывного взаимодействия.
requestAnimationFrame –
для крупных массивов данных анимация будет более плавной при вызове
перестроения внутри requestAnimationFrame.Фильтры обычно связываются с элементами интерфейса, например кнопками или селекторами:
var buttons = document.querySelectorAll('.filter-button-group button');
buttons.forEach(button => {
button.addEventListener('click', function() {
var filterValue = button.getAttribute('data-filter');
applyFilter(filterValue);
});
});
Каждое нажатие кнопки отправляет новый запрос на сервер и обновляет сетку с учётом выбранного фильтра.