Masonry — это библиотека для динамической сетки элементов, которая автоматически располагает блоки на странице в оптимальном порядке, создавая «каскадный» эффект. Одним из ключевых аспектов её работы является способность автоматически обновлять расположение элементов при изменении DOM или размеров элементов. Понимание механизмов, которые инициируют перерасчёт сетки, критично для оптимальной производительности и корректного отображения.
layout() и его
рольОсновным механизмом перераспределения элементов является метод
layout(). Он пересчитывает позиции всех
элементов сетки, гарантируя, что каждый блок занимает правильное
место.
var msnry = new Masonry('.grid', {
itemSelector: '.grid-item',
columnWidth: 200
});
// Пересчёт сетки вручную
msnry.layout();
Ключевой момент: вызов layout() не
происходит автоматически при изменении контента — это ручной триггер.
Чтобы Masonry обновлял позиции автоматически, необходимо использовать
специальные события или методы наблюдения изменений DOM.
imagesLoadedОдной из наиболее частых причин некорректного позиционирования
является динамическая загрузка изображений. Если
элементы сетки содержат изображения, размеры которых неизвестны до
полной загрузки, Masonry может разместить блоки неправильно. Для решения
используется библиотека imagesLoaded:
imagesLoaded('.grid', function() {
msnry.layout();
});
Суть триггера: Masonry ожидает, пока все изображения загрузятся, и только после этого пересчитывает позиции. Это предотвращает перескакивание элементов при окончательной подгрузке картинок.
Для автоматического реагирования на изменения DOM применяются MutationObserver. Он позволяет следить за добавлением, удалением или изменением элементов внутри контейнера Masonry.
var observer = new MutationObserver(function(mutations) {
msnry.layout();
});
observer.observe(document.querySelector('.grid'), {
childList: true,
subtree: true
});
Особенности:
childList: true — отслеживает добавление и удаление
элементов.subtree: true — включает наблюдение за вложенными
элементами.layout() автоматически, что
делает сетку «живой» и адаптивной к динамическому контенту.Если размеры элементов сетки изменяются динамически (например, через CSS или JavaScript), Masonry должен реагировать на это изменение. Здесь используется ResizeObserver:
var resizeObserver = new ResizeObserver(() => {
msnry.layout();
});
document.querySelectorAll('.grid-item').forEach(item => {
resizeObserver.observe(item);
});
Особенности работы:
Для максимально надёжного автоматического обновления рекомендуется сочетать:
imagesLoaded — для обработки загружаемых
изображений.MutationObserver — для отслеживания добавления и
удаления элементов.ResizeObserver — для реагирования на изменение размеров
существующих элементов.Пример комплексного подхода:
imagesLoaded('.grid', function() {
msnry.layout();
});
var observer = new MutationObserver(() => msnry.layout());
observer.observe(document.querySelector('.grid'), { childList: true, subtree: true });
var resizeObserver = new ResizeObserver(() => msnry.layout());
document.querySelectorAll('.grid-item').forEach(item => resizeObserver.observe(item));
Такой подход гарантирует, что сетка всегда будет актуальна, независимо от загрузки изображений, динамического контента или изменения размеров блоков.
Автоматические триггеры создают дополнительную нагрузку на рендеринг страницы. Чтобы минимизировать её:
layout() только после того, как изменения
завершены, а не при каждом мелком событии.let timeout;
var resizeObserver = new ResizeObserver(() => {
clearTimeout(timeout);
timeout = setTimeout(() => msnry.layout(), 100);
});
Вывод: контроль над триггерами Masonry позволяет создавать динамические и стабильные сетки, сохраняя производительность даже при изменяющемся контенте и размерах элементов.