Packery — это библиотека для построения динамических сеток с поддержкой «мозайки» и свободного размещения элементов. Одной из ключевых возможностей является фильтрация элементов, что позволяет создавать интерактивные интерфейсы с динамическим отображением контента. Комбинирование фильтров открывает широкие возможности для гибкой работы с элементами сетки.
В Packery фильтры применяются через CSS-классы или произвольные функции. Каждый элемент сетки может иметь несколько классов, что позволяет создавать сложные условия фильтрации.
Пример классов элементов:
<div class="grid">
<div class="item red large"></div>
<div class="item blue small"></div>
<div class="item green medium"></div>
<div class="item red small"></div>
</div>
Здесь red, blue, green
отвечают за цвет, а large, medium,
small — за размер элементов. Комбинируя эти классы, можно
создавать фильтры, которые учитывают одновременно несколько
параметров.
Наиболее простой способ фильтрации — использование селекторов CSS:
var pckry = new Packery('.grid', {
itemSelector: '.item',
gutter: 10
});
function filterItems(color, size) {
var selector = '.' + color + '.' + size;
pckry.items.forEach(function(item) {
if (!item.element.matches(selector)) {
item.element.style.display = 'none';
} else {
item.element.style.display = '';
}
});
pckry.layout();
}
filterItems('red', 'small'); // покажет только элементы с классами red и small
Ключевой момент: селекторы комбинируются через точку
без пробелов (.red.small), что означает элемент, который
одновременно имеет оба класса.
Packery позволяет использовать функции для более сложной логики
фильтрации. Функция должна возвращать true для элементов,
которые нужно показать, и false для скрытия.
function filterFunction(itemElem) {
var color = itemElem.classList.contains('red');
var size = itemElem.classList.contains('small');
return color && size; // одновременно красный и маленький
}
pckry.items.forEach(function(item) {
if (!filterFunction(item.element)) {
item.element.style.display = 'none';
} else {
item.element.style.display = '';
}
});
pckry.layout();
Функциональная фильтрация особенно полезна, когда необходимо учитывать динамические условия, например, свойства данных, которые не представлены классами.
Часто возникает необходимость одновременно применять несколько фильтров, таких как цвет и размер, или состояние элемента. Для этого можно использовать несколько методов:
&&) — элемент
отображается, если выполняются все условия фильтров.||) — элемент
отображается, если выполняется хотя бы одно из условий.var filters = [
function(item) { return item.classList.contains('red'); },
function(item) { return item.classList.contains('large'); }
];
pckry.items.forEach(function(item) {
var visible = filters.every(f => f(item.element)); // логическое И
item.element.style.display = visible ? '' : 'none';
});
pckry.layout();
Использование every соответствует логическому И между
фильтрами, а some — логическому ИЛИ.
Для интерактивных интерфейсов фильтры часто привязываются к кнопкам или чекбоксам. При изменении состояния элементов формы необходимо пересчитывать фильтры и обновлять сетку:
var buttons = document.querySelectorAll('.filter-button');
buttons.forEach(function(button) {
button.addEventListener('click', function() {
var color = button.dataset.color;
var size = button.dataset.size;
filterItems(color, size);
});
});
При таком подходе комбинируются фильтры из различных источников: пользовательский выбор, данные элемента и динамические условия.
Для продвинутых интерфейсов фильтры можно хранить в объекте состояния и применять их на лету:
var activeFilters = { color: 'red', size: 'small', visible: true };
function dynamicFilter(itemElem) {
var matchColor = activeFilters.color ? itemElem.classList.contains(activeFilters.color) : true;
var matchSize = activeFilters.size ? itemElem.classList.contains(activeFilters.size) : true;
return matchColor && matchSize && activeFilters.visible;
}
pckry.items.forEach(function(item) {
item.element.style.display = dynamicFilter(item.element) ? '' : 'none';
});
pckry.layout();
Такой подход позволяет легко добавлять новые фильтры и комбинировать их без необходимости переписывать основную логику.
При работе с большим количеством элементов важно минимизировать
количество перерисовок. Вместо вызова pckry.layout() после
каждого изменения, рекомендуется сначала скрыть/показать все элементы, а
затем вызвать layout один раз:
pckry.items.forEach(function(item) {
item.element.style.display = dynamicFilter(item.element) ? '' : 'none';
});
pckry.layout();
Это существенно снижает нагрузку на браузер и делает анимацию фильтрации плавной.
Packery поддерживает CSS-анимацию при изменении положения элементов. Для этого достаточно определить переходы в стилях:
.item {
transition: transform 0.4s, opacity 0.4s;
}
.item[style*="display: none"] {
opacity: 0;
}
Фильтры будут одновременно скрывать/показывать элементы и плавно перераспределять сетку, создавая визуально привлекательный интерфейс.
Эти механизмы комбинирования фильтров позволяют создавать гибкие, масштабируемые и интерактивные сетки в Packery, обеспечивая поддержку сложных условий отображения элементов.