Интеграция с imagesLoaded

Для корректной работы Masonry с изображениями необходимо учитывать, что стандартная инициализация сетки не всегда гарантирует правильное расположение элементов до полной загрузки всех изображений. Для решения этой задачи используется библиотека imagesLoaded, которая позволяет отследить момент, когда все изображения внутри контейнера полностью загружены.

Подключение осуществляется стандартным способом:

<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>

В современных проектах часто применяют сборщики модулей, и подключение может выглядеть так:

import Masonry from 'masonry-layout';
import imagesLoaded from 'imagesloaded';

Инициализация Masonry с учётом загрузки изображений

После подключения библиотек создается экземпляр Masonry, указываются контейнер и элементы сетки:

const grid = document.querySelector('.grid');

const msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer',
  percentPosition: true,
  gutter: 10
});

Однако, если изображения имеют разную высоту и загружаются асинхронно, сетка может сломаться. Для корректного расположения применяется imagesLoaded:

imagesLoaded(grid).on('progress', function() {
  msnry.layout();
});
  • progress — событие, которое срабатывает каждый раз при загрузке отдельного изображения.
  • msnry.layout() — пересчитывает позиции элементов в сетке после загрузки каждого изображения.

Использование progress позволяет избежать “скачков” макета и обеспечивает плавное формирование сетки.


Полная обработка загрузки всех изображений

В некоторых случаях требуется дождаться загрузки всех изображений перед выполнением каких-либо действий, например, анимации или отображения контента:

imagesLoaded(grid, function() {
  msnry.layout();
  console.log('Все изображения загружены');
});

Это гарантирует, что Masonry расставит все элементы правильно один раз, когда контент полностью готов.


Отслеживание добавления новых элементов

Для динамически добавляемых элементов важно корректно интегрировать Masonry с imagesLoaded:

function addItem(html) {
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = html;
  const newItem = tempDiv.firstElementChild;
  
  grid.appendChild(newItem);
  
  imagesLoaded(newItem, function() {
    msnry.appended(newItem);
    msnry.layout();
  });
}
  • msnry.appended(newItem) — уведомляет Masonry о добавлении нового элемента.
  • После загрузки изображения сетка пересчитывает позиции.

Этот подход особенно полезен для ленивой подгрузки контента и бесконечных скроллов.


Использование событий imagesLoaded для анимаций

Можно комбинировать Masonry и анимации с помощью событий imagesLoaded:

imagesLoaded(grid).on('progress', function(instance, image) {
  image.img.classList.add('fade-in');
  msnry.layout();
});
  • instance — объект imagesLoaded для контейнера.
  • image — объект отдельного изображения с полями img и isLoaded.
  • Класс fade-in может содержать CSS-анимацию появления элементов.

Такой подход обеспечивает одновременное соблюдение сетки Masonry и визуально приятное появление контента.


Рекомендации по производительности

  1. Использовать percentPosition: true при гибкой верстке и адаптивной сетке.
  2. Минимизировать количество вызовов layout() — вызывать пересчет после загрузки нескольких изображений, а не каждого по отдельности, если сетка очень большая.
  3. Подгружать изображения с фиксированной шириной или использовать grid-sizer для более предсказуемой расстановки элементов.
  4. Комбинировать с ленивой загрузкой (lazy-loading) и проверкой imagesLoaded для динамически создаваемых блоков, чтобы сетка не “ломалась” при асинхронной подгрузке.

Итоговая структура использования

const grid = document.querySelector('.grid');

const msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer',
  percentPosition: true,
  gutter: 10
});

imagesLoaded(grid).on('progress', function() {
  msnry.layout();
});

// Для динамического добавления элементов
function addItem(html) {
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = html;
  const newItem = tempDiv.firstElementChild;
  
  grid.appendChild(newItem);
  
  imagesLoaded(newItem, function() {
    msnry.appended(newItem);
    msnry.layout();
  });
}

Такой подход обеспечивает корректное отображение сетки Masonry с любым количеством изображений, предотвращает наложение элементов и позволяет плавно интегрировать динамический контент.