Фильтрация на стороне сервера

Для работы с библиотекой 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 позволяет сортировать элементы по заданным критериям, например, по имени или категории.


Принципы фильтрации на стороне сервера

Фильтрация на стороне сервера предполагает, что клиент получает не весь массив данных сразу, а только необходимый под запрос набор. В отличие от клиентской фильтрации, где все элементы уже находятся на странице, серверная фильтрация уменьшает нагрузку на браузер и ускоряет работу с большим объёмом данных.

Основные этапы реализации:

  1. Формирование запроса к серверу – отправка параметров фильтрации (категория, диапазон цен, тег и т.д.) через AJAX или fetch.
  2. Обработка запроса на сервере – сервер выполняет фильтрацию данных и возвращает JSON с нужными элементами.
  3. Обновление Isotope – на клиенте удаляются старые элементы и добавляются новые с применением метода appended или reloadItems.

Пример запроса через fetch:

function fetchFilteredData(filter) {
  fetch(`/api/items?category=${filter}`)
    .then(response => response.json())
    .then(data => {
      updateIsotopeGrid(data);
    });
}

Обновление сетки Isotope после получения данных

После получения массива элементов от сервера необходимо правильно интегрировать их в 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);
}

После получения новых данных сетка автоматически перестраивается с анимацией, создавая ощущение непрерывного взаимодействия.


Особенности производительности

  1. Минимизация DOM-операций – сначала формировать фрагмент документа, затем добавлять его в контейнер.
  2. Использование requestAnimationFrame – для крупных массивов данных анимация будет более плавной при вызове перестроения внутри requestAnimationFrame.
  3. Постраничная загрузка – загружать данные по частям, чтобы не перегружать браузер и поддерживать отзывчивость интерфейса.
  4. Кэширование – при повторных фильтрах можно хранить ранее загруженные данные, чтобы избежать лишних запросов к серверу.

Интеграция с пользовательским интерфейсом

Фильтры обычно связываются с элементами интерфейса, например кнопками или селекторами:

var buttons = document.querySelectorAll('.filter-button-group button');
buttons.forEach(button => {
  button.addEventListener('click', function() {
    var filterValue = button.getAttribute('data-filter');
    applyFilter(filterValue);
  });
});

Каждое нажатие кнопки отправляет новый запрос на сервер и обновляет сетку с учётом выбранного фильтра.