Использование imagesLoaded

Для корректного позиционирования элементов в сетке 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 одновременно

Иногда встречается комбинация библиотек Masonry и Packery. Для корректной работы важно вызывать imagesLoaded перед инициализацией сетки:

imagesLoaded(grid, function() {
  var pckry = new Packery(grid, {
    itemSelector: '.grid-item',
    gutter: 10
  });
});

В этом случае Packery создаётся только после того, как все изображения получили свои окончательные размеры, что исключает сдвиги и накладки элементов.

Настройка callback для частичной загрузки

Для анимаций или постепенного появления элементов можно использовать 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> тегами
  • CSS background images через опцию background: true:
imagesLoaded(grid, { background: true }).on('always', function() {
  pckry.layout();
});

Это особенно важно, если сетка использует карточки с фоновой графикой, а не только <img>.

Совместимость и интеграция

  • imagesLoaded совместима со всеми современными браузерами.
  • Обеспечивает работу Packery с сетками, где размеры элементов заранее неизвестны.
  • Хорошо интегрируется с анимационными библиотеками, например GSAP, позволяя запускать анимации после полной загрузки изображений.

Эффективное сочетание Packery и imagesLoaded гарантирует стабильное, корректное и предсказуемое размещение элементов сетки независимо от скорости загрузки изображений и динамического добавления контента.