Packery — это JavaScript-библиотека для организации элементов на странице в виде сетки с поддержкой динамических размеров элементов. Она позволяет создавать плотные, упорядоченные и адаптивные сетки с возможностью «упаковки» элементов в минимальное пространство, избегая пустых промежутков. Packery особенно эффективна для реализации интерфейсов типа «masonry», где размеры элементов могут быть разными.
Подключение библиотеки осуществляется через CDN или локально:
<script src="https://unpkg.com/packery@2/dist/packery.pkgd.min.js"></script>
Инициализация сетки выполняется на контейнере, содержащем элементы:
const grid = document.querySelector('.grid');
const pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
itemSelector — CSS-селектор элементов, которые будут
размещены внутри сетки.gutter — отступ между элементами, задается в
пикселях.Packery поддерживает динамическое изменение содержимого контейнера. Добавление новых элементов выполняется следующим образом:
const newItem = document.createElement('div');
newItem.classList.add('grid-item');
newItem.textContent = 'Новый элемент';
grid.appendChild(newItem);
pckry.appended(newItem);
Для удаления элементов используется метод remove:
pckry.remove(newItem);
pckry.layout();
Важно всегда вызывать layout() после удаления, чтобы
сетка пересчиталась и элементы заняли оптимальные позиции.
Packery интегрируется с библиотекой Draggabilly, что позволяет перетаскивать элементы и автоматически перестраивать сетку.
<script src="https://unpkg.com/draggabilly@2/dist/draggabilly.pkgd.min.js"></script>
Привязка перетаскивания:
const draggies = [];
pckry.getItemElements().forEach(function(itemElem) {
const draggie = new Draggabilly(itemElem);
pckry.bindDraggabillyEvents(draggie);
draggies.push(draggie);
});
Ключевые моменты:
getItemElements() возвращает массив DOM-элементов
сетки.bindDraggabillyEvents(draggie) синхронизирует Packery с
перетаскиванием, позволяя элементам занимать новые позиции без
разрушения сетки.Packery учитывает размеры элементов в пикселях и процентах. Для обеспечения адаптивности рекомендуется комбинировать Packery с CSS Flexbox или Grid:
.grid {
width: 100%;
}
.grid-item {
width: 30%;
margin-bottom: 10px;
}
При изменении размеров контейнера необходимо вызвать метод
layout() для пересчета позиций:
window.addEventListener('resize', () => {
pckry.layout();
});
Packery предоставляет собственные события, которые позволяют реагировать на изменения сетки:
layoutComplete — вызывается после завершения
перестановки элементов.dragItemPositioned — вызывается после завершения
перетаскивания элемента.Пример подписки на события:
pckry.on('layoutComplete', function(event, laidOutItems) {
console.log('Сетка обновлена', laidOutItems);
});
pckry.on('dragItemPositioned', function(event, draggedItem) {
console.log('Элемент перемещен', draggedItem.element);
});
Packery может быть совместно использована с различными библиотеками визуализации и интерфейсов. Например:
Пример интеграции с ImagesLoaded:
<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
imagesLoaded(grid, function() {
pckry.layout();
});
Это гарантирует, что Packery выполнит расчет сетки только после полной загрузки всех изображений, предотвращая наложение элементов.
При больших сетках важно учитывать производительность:
percentPosition: true для работы с
процентными ширинами элементов.layout() при массовых
изменениях.appended() и remove()
вместо полной перестройки сетки через reloadItems() для
динамических операций.Packery предоставляет расширенные опции:
originLeft и originTop — контроль
направления упаковки.rowHeight — фиксированная высота ряда для упрощения
расчета.stamp() — позволяет закрепить элемент в сетке, вокруг
которого другие элементы будут упаковываться.Пример использования stamp:
const stampElem = document.querySelector('.stamp');
pckry.stamp(stampElem);
pckry.layout();
Это особенно полезно для создания сеток с постоянными баннерами или рекламными блоками.
Packery сочетает гибкость и мощные возможности управления сеткой, предоставляя разработчику полный контроль над размещением элементов, поддержкой динамических данных и интеграцией с другими библиотеками.