Masonry — это библиотека для создания сеточных макетов с «кирпичной» структурой. Управление состоянием фильтров в ней строится вокруг динамического показа и скрытия элементов, а также пересчета расположения элементов после применения фильтра. Фильтрация позволяет отображать только те элементы, которые соответствуют определённым критериям, не перезагружая страницу.
Элементы для Masonry обычно имеют общий контейнер, например:
<div class="grid">
<div class="grid-item category-a">Элемент 1</div>
<div class="grid-item category-b">Элемент 2</div>
<div class="grid-item category-a">Элемент 3</div>
<div class="grid-item category-c">Элемент 4</div>
</div>
Инициализация Masonry:
const grid = document.querySelector('.grid');
const msnry = new Masonry(grid, {
itemSelector: '.grid-item',
columnWidth: '.grid-item',
percentPosition: true
});
Фильтры можно реализовать через атрибуты или классы элементов. Основная идея — при выборе фильтра скрывать элементы, которые не соответствуют критерию, и пересчитывать макет.
function filterItems(category) {
const items = grid.querySelectorAll('.grid-item');
items.forEach(item => {
if (category === 'all' || item.classList.contains(category)) {
item.style.display = '';
} else {
item.style.display = 'none';
}
});
msnry.layout();
}
В этом примере:
category === 'all' — показывает все элементы.item.style.display = '' — возвращает элемент в поток
документа.msnry.layout() — пересчитывает расположение видимых
элементов после изменения отображения.Для поддержания состояния фильтров используется отдельная переменная:
let activeFilter = 'all';
const filterButtons = document.querySelectorAll('.filter-button');
filterButtons.forEach(button => {
button.addEventListener('click', () => {
activeFilter = button.dataset.filter;
filterItems(activeFilter);
updateActiveClass(button);
});
});
function updateActiveClass(button) {
filterButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
}
Здесь:
activeFilter хранит текущий выбранный фильтр.data-filter на кнопках соответствует классам
элементов.updateActiveClass обновляет визуальное
состояние кнопок.Для плавного исчезновения и появления элементов используется CSS-переход:
.grid-item {
transition: transform 0.3s, opacity 0.3s;
}
.grid-item.hidden {
opacity: 0;
transform: scale(0.8);
pointer-events: none;
}
Функция фильтрации с анимацией:
function filterItemsAnimated(category) {
const items = grid.querySelectorAll('.grid-item');
items.forEach(item => {
if (category === 'all' || item.classList.contains(category)) {
item.classList.remove('hidden');
} else {
item.classList.add('hidden');
}
});
msnry.layout();
}
Преимущество такого подхода: элементы исчезают и появляются плавно, сохраняя общий визуальный ритм сетки.
Можно комбинировать несколько фильтров, используя массивы и логические условия:
let activeFilters = [];
function toggleFilter(filter) {
const index = activeFilters.indexOf(filter);
if (index > -1) {
activeFilters.splice(index, 1);
} else {
activeFilters.push(filter);
}
applyMultipleFilters();
}
function applyMultipleFilters() {
const items = grid.querySelectorAll('.grid-item');
items.forEach(item => {
const matches = activeFilters.length === 0 || activeFilters.some(f => item.classList.contains(f));
item.style.display = matches ? '' : 'none';
});
msnry.layout();
}
activeFilters — массив всех активных фильтров.some проверяет, соответствует ли элемент хотя бы
одному фильтру.Masonry поддерживает события layoutComplete и
removeComplete, которые помогают отслеживать изменения
после фильтрации:
msnry.on('layoutComplete', function() {
console.log('Макет обновлён после фильтрации');
});
Эти события полезны для динамических интерфейсов, где после фильтрации нужно выполнять дополнительные действия, например, загружать контент через AJAX или обновлять счётчик элементов.
Для корректной работы с изображениями нужно учитывать, что Masonry
рассчитывает макет после загрузки контента. Используется библиотека
imagesLoaded:
imagesLoaded(grid, () => {
msnry.layout();
});
Это гарантирует, что элементы с изображениями правильно расположены, даже если изображения загружаются асинхронно.
msnry.layout() только после того, как все элементы скрыты
или показаны.Эти методы обеспечивают стабильную работу фильтров даже при больших сетках с сотнями элементов.