Packery — это библиотека для построения сетки с «упорядоченным хаосом», где элементы автоматически располагаются компактно, учитывая размеры соседей. Ключевой момент при работе с динамическим контентом — правильная инициализация сетки только после того, как все элементы и их ресурсы полностью загружены.
Если попытаться инициализировать Packery до загрузки изображений или другого контента, сетка может быть построена некорректно: элементы перекроются, возникнут пустые промежутки, размеры будут рассчитаны неправильно.
const grid = document.querySelector('.grid');
imagesLoaded(grid, function() {
const pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
});
В этом примере используется библиотека imagesLoaded, которая обеспечивает корректное определение момента полной загрузки всех изображений в контейнере. Это обязательный шаг при работе с медиа-контентом, размеры которого заранее неизвестны.
layoutCompletePackery предоставляет событие layoutComplete, которое
можно использовать для выполнения действий после того, как сетка
полностью отрендерена:
pckry.on('layoutComplete', function(items) {
console.log('Сетка обновлена, количество элементов:', items.length);
});
Это позволяет отслеживать завершение компоновки элементов, добавлять анимации, или производить дополнительные манипуляции с DOM после построения сетки.
При добавлении новых элементов в уже существующую сетку важно ожидать завершения загрузки ресурсов каждого нового элемента:
const newItem = document.createElement('div');
newItem.className = 'grid-item';
newItem.innerHTML = '<img src="image.jpg">';
grid.appendChild(newItem);
imagesLoaded(newItem, function() {
pckry.appended(newItem);
pckry.layout();
});
Метод pckry.appended() добавляет новые элементы в сетку
без полной перезагрузки, а pckry.layout() пересчитывает
расположение. Если вызвать их до загрузки изображения, элемент может
появиться с нулевыми размерами, что нарушит гармонию сетки.
Если контент загружается с сервера через AJAX или fetch, необходимо строить Packery только после полного добавления DOM-элементов и завершения загрузки всех медиа:
fetch('/api/items')
.then(res => res.json())
.then(data => {
const fragment = document.createDocumentFragment();
data.forEach(itemData => {
const item = document.createElement('div');
item.className = 'grid-item';
item.innerHTML = `<img src="${itemData.img}">`;
fragment.appendChild(item);
});
grid.appendChild(fragment);
imagesLoaded(grid, function() {
pckry.reloadItems();
pckry.layout();
});
});
Использование reloadItems() важно после массового
добавления элементов, так как Packery иначе не узнает о новых
DOM-узлах.
Packery корректно работает не только с изображениями, но и с видео, iframe и любым динамическим контентом. В таких случаях также необходимо отслеживать момент полной загрузки контента:
const videos = grid.querySelectorAll('video');
let loadedCount = 0;
videos.forEach(video => {
video.onloadedd ata = () => {
loadedCount++;
if (loadedCount === videos.length) {
pckry.layout();
}
};
});
Подход универсален: любые элементы, размеры которых неизвестны заранее, должны дождаться полной загрузки перед вызовом методов Packery, иначе сетка нарушит свою геометрию.
imagesLoaded или аналогичных
инструментов для отслеживания готовности контента.layoutComplete позволяет
реагировать на завершение перестройки сетки.append и
reloadItems корректно обновляют сетку при
динамическом добавлении элементов.Этот подход обеспечивает стабильность и предсказуемость расположения элементов, предотвращает визуальные артефакты и пустые промежутки, делая работу Packery надежной даже при сложных динамических интерфейсах.