Для корректного позиционирования элементов в сетке Packery важно,
чтобы все изображения внутри контейнера были полностью загружены.
Библиотека imagesLoaded решает эту задачу, позволяя
запускать расчёт сетки только после загрузки всех изображений.
Стандартный подход выглядит следующим образом:
var grid = document.querySelector('.grid');
var pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
imagesLoaded(grid).on('progress', function(instance, image) {
pckry.layout();
});
Ключевые моменты:
imagesLoaded(grid) создаёт объект, отслеживающий
загрузку всех изображений внутри элемента .grid.progress срабатывает каждый раз, когда
отдельное изображение завершает загрузку.pckry.layout(), чтобы
Packery перестроил сетку с учётом размеров уже загруженных
изображений.В случае когда важно дождаться полной загрузки всех изображений перед
первичной визуализацией сетки, используется событие
always:
imagesLoaded(grid).on('always', function(instance) {
pckry.layout();
});
В отличие от progress, событие always
срабатывает только один раз после загрузки всех изображений. Это полезно
для предотвращения многократного пересчёта сетки при большом количестве
элементов.
Packery часто используется для сеток, где элементы добавляются
динамически. В таких случаях необходимо интегрировать
imagesLoaded с добавлением новых элементов:
var newItem = document.createElement('div');
newItem.className = 'grid-item';
newItem.innerHTML = '<img src="example.jpg">';
grid.appendChild(newItem);
imagesLoaded(newItem).on('always', function() {
pckry.appended(newItem);
pckry.layout();
});
Особенности:
imagesLoaded(newItem) отслеживает только новые
изображения.pckry.appended(newItem),
чтобы Packery зарегистрировал новый элемент.pckry.layout() обновляет расположение всех элементов с
учётом нового.Если на странице несколько сеток Packery, необходимо создавать
отдельные экземпляры imagesLoaded для каждого
контейнера:
var grids = document.querySelectorAll('.grid');
grids.forEach(function(grid) {
var pckry = new Packery(grid, { itemSelector: '.grid-item', gutter: 10 });
imagesLoaded(grid).on('always', function() {
pckry.layout();
});
});
Иногда встречается комбинация библиотек Masonry и Packery. Для
корректной работы важно вызывать imagesLoaded перед
инициализацией сетки:
imagesLoaded(grid, function() {
var pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
});
В этом случае Packery создаётся только после того, как все изображения получили свои окончательные размеры, что исключает сдвиги и накладки элементов.
Для анимаций или постепенного появления элементов можно использовать
progress с дополнительной логикой:
imagesLoaded(grid).on('progress', function(instance, image) {
image.img.classList.add('loaded');
pckry.layout();
});
loaded позволяет применять
CSS-анимации для каждого изображения по мере загрузки.pckry.layout() обеспечивает
корректное расположение оставшихся элементов сетки.При большом количестве изображений многократные вызовы
pckry.layout() могут снижать производительность.
Рекомендуется:
requestAnimationFrame для дебаунса
пересчёта:imagesLoaded(grid).on('progress', function() {
requestAnimationFrame(function() {
pckry.layout();
});
});
pckry.layout().imagesLoaded корректно работает с:
<img> тегамиbackground: true:imagesLoaded(grid, { background: true }).on('always', function() {
pckry.layout();
});
Это особенно важно, если сетка использует карточки с фоновой
графикой, а не только <img>.
imagesLoaded совместима со всеми современными
браузерами.GSAP, позволяя запускать анимации после полной загрузки
изображений.Эффективное сочетание Packery и imagesLoaded гарантирует стабильное, корректное и предсказуемое размещение элементов сетки независимо от скорости загрузки изображений и динамического добавления контента.