Базовая фильтрация

Masonry — это популярная библиотека для построения динамических сеток с «кирпичной» компоновкой, позволяющая размещать элементы разной высоты и ширины без пустых промежутков. Одной из ключевых возможностей является фильтрация элементов, что позволяет отображать только определённые группы элементов на странице.

Подключение и инициализация

Для работы с Masonry необходимо подключить саму библиотеку и элементы контейнера. Обычно структура HTML выглядит так:

<div class="grid">
  <div class="grid-item category-a">Элемент A1</div>
  <div class="grid-item category-b">Элемент B1</div>
  <div class="grid-item category-a">Элемент A2</div>
  <div class="grid-item category-c">Элемент C1</div>
</div>

Инициализация Masonry выполняется через Jav * aScript:

var grid = document.querySelector('.grid');

var msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer', // Если используется элемент для сетки
  percentPosition: true
});

Важно: itemSelector определяет, какие элементы Masonry будет располагать в сетке.

Основной принцип фильтрации

Фильтрация в Masonry не встроена напрямую, но её можно реализовать с помощью показать/скрыть элементов через CSS и последующего вызова метода layout():

function filterItems(category) {
  var items = grid.querySelectorAll('.grid-item');

  items.forEach(function(item) {
    if (item.classList.contains(category) || category === 'all') {
      item.style.display = '';
    } else {
      item.style.display = 'none';
    }
  });

  msnry.layout();
}
  • category — класс, по которому производится фильтрация.
  • msnry.layout() — пересчитывает положение элементов после изменения видимости.

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

Для управления фильтрацией можно использовать кнопки:

<div class="filters">
  <button data-filter="all">Все</button>
  <button data-filter="category-a">Категория A</button>
  <button data-filter="category-b">Категория B</button>
  <button data-filter="category-c">Категория C</button>
</div>

Привязка события клика к фильтрам:

var filterButtons = document.querySelectorAll('.filters button');

filterButtons.forEach(function(button) {
  button.addEventListener('click', function() {
    var filterValue = button.getAttribute('data-filter');
    filterItems(filterValue);
  });
});

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

Для более плавного визуального эффекта можно использовать CSS-трансформации вместо display: none;. Пример:

.grid-item {
  transition: transform 0.3s, opacity 0.3s;
}

.grid-item.hidden {
  opacity: 0;
  transform: scale(0.5);
  pointer-events: none;
}

И обновлённый Jav * aScript:

function filterItems(category) {
  var items = grid.querySelectorAll('.grid-item');

  items.forEach(function(item) {
    if (item.classList.contains(category) || category === 'all') {
      item.classList.remove('hidden');
    } else {
      item.classList.add('hidden');
    }
  });

  msnry.layout();
}

Такой подход обеспечивает плавное исчезновение и появление элементов, сохраняя расположение сетки.

Совмещение с динамическим добавлением элементов

Если элементы добавляются после инициализации Masonry, необходимо использовать методы append и layout:

var newItem = document.createElement('div');
newItem.className = 'grid-item category-b';
newItem.textContent = 'Новый элемент B2';

grid.appendChild(newItem);
msnry.appended(newItem);
msnry.layout();

При фильтрации таких динамических элементов они будут корректно отображаться или скрываться.

Важные моменты при фильтрации

  • Всегда вызов msnry.layout() после изменения видимости элементов. Без него Masonry не пересчитает сетку.
  • При использовании анимаций через класс .hidden элементы остаются в DOM, что позволяет Masonry корректно рассчитывать позиции соседних элементов.
  • Фильтрация по нескольким категориям возможна через массив классов:
function filterItems(categories) {
  var items = grid.querySelectorAll('.grid-item');

  items.forEach(function(item) {
    var match = categories.some(category => item.classList.contains(category));
    if (match || categories.includes('all')) {
      item.classList.remove('hidden');
    } else {
      item.classList.add('hidden');
    }
  });

  msnry.layout();
}

Интеграция с библиотекой imagesLoaded

Если сетка содержит изображения, необходимо убедиться, что Masonry пересчитает позиции после загрузки изображений:

imagesLoaded(grid, function() {
  msnry.layout();
});

Это предотвращает смещение элементов и пустые промежутки при фильтрации.

Резюме технических приёмов

  • Фильтрация через классы: управляет видимостью элементов.
  • Метод layout(): пересчитывает расположение элементов Masonry после изменений.
  • Анимации с CSS: обеспечивают плавное появление/исчезновение.
  • Поддержка динамических элементов: использование append и appended.
  • Совместимость с изображениями: через imagesLoaded.

Эта методика обеспечивает гибкую и эффективную фильтрацию элементов в Masonry без потери производительности и визуальной стабильности сетки.