layout и layoutItems

Masonry — это библиотека JavaScript, предназначенная для динамического расположения элементов в сетке с плавающими блоками, где каждый блок «подстраивается» под доступное пространство. Основные понятия при работе с Masonry — это layout и layoutItems. Понимание их взаимодействия критично для точного контроля расположения элементов и оптимизации производительности.


Layout

Layout в Masonry — это объект, управляющий расположением всех элементов сетки. Он отвечает за расчёт координат каждого блока и обработку их перемещений при изменении размеров контейнера или добавлении новых элементов.

Основные свойства layout:

  • container — DOM-элемент, в котором размещается сетка. Все расчёты координат ведутся относительно него.
  • items — массив объектов layoutItem, который хранит все элементы текущей сетки.
  • cols — количество колонок, на которое Masonry разбивает контейнер для распределения элементов. Вычисляется автоматически на основе ширины контейнера и заданной ширины колонки.
  • colYs — массив, где каждый индекс соответствует текущей нижней координате последнего элемента в колонке. Используется для расчёта позиции нового блока.

Методы layout

  • layoutItems(items, isInstant) — главный метод, выполняющий расчёт и расположение элементов. items — массив объектов layoutItem, которые нужно разместить; isInstant — флаг, определяющий, нужно ли размещать элементы без анимации.
  • **_resetLayout()** — внутренний метод, сбрасывающий текущие значения колонок и координат.
  • **_getItemLayoutPosition(item)** — вычисляет координаты x и y для отдельного элемента на основе текущего состояния колонок.
  • **_manageStamp(stamp)** — учитывает «штампы» (статические элементы, не участвующие в сетке, но влияющие на позицию остальных блоков).

Принцип работы

  1. Masonry делит контейнер на виртуальные колонки.
  2. Для каждого элемента вычисляется наименьшая по высоте колонка.
  3. Элемент помещается в эту колонку, обновляется colYs.
  4. При изменении размера контейнера или добавлении новых элементов выполняется перерасчёт позиций всех или выбранных layoutItems.

LayoutItem

LayoutItem — это объект, представляющий отдельный элемент сетки и инкапсулирующий его состояние. Каждый элемент контейнера преобразуется в layoutItem при инициализации Masonry или при динамическом добавлении.

Основные свойства layoutItem:

  • element — сам DOM-элемент, который Masonry будет размещать.
  • size — объект с шириной и высотой элемента.
  • position — текущие координаты x и y.
  • isIgnored — флаг, определяющий, должен ли элемент участвовать в расчётах (например, скрытые элементы или «штампы»).

Методы layoutItem:

  • getSize() — вычисляет размеры элемента с учётом внешних отступов (margin) и border-box модели.
  • applyPosition() — применяет рассчитанные координаты к стилям элемента (style.top, style.left).
  • transitionTo(x, y) — анимированное перемещение элемента на новые координаты.
  • measure() — обновляет информацию о текущей ширине и высоте элемента, если его размеры изменились динамически.

Взаимодействие с layout

Каждый layoutItem передаётся в layout при вызове layoutItems(). Layout использует методы layoutItem для вычисления позиции и применения стилей. При этом Masonry обеспечивает:

  • минимизацию пересчётов при изменении размера контейнера;
  • корректное позиционирование при динамическом добавлении или удалении элементов;
  • поддержку анимации без разрыва сетки.

Оптимизация и управление

  • Фильтрация элементов: через isIgnored можно исключать элементы из расчётов, что ускоряет работу при больших сетках.
  • Перерасчёт размеров: использование метода measure() для динамических элементов предотвращает наложение блоков.
  • Анимации: флаг isInstant в layoutItems() позволяет выбирать между мгновенным расположением и плавной анимацией.

Пример взаимодействия layout и layoutItems

import Masonry from 'masonry-layout';

const grid = document.querySelector('.grid');
const msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: 200,
  gutter: 10
});

// Добавление нового элемента
const itemElem = document.createElement('div');
itemElem.className = 'grid-item';
grid.appendChild(itemElem);

const layoutItem = msnry.getItem(itemElem);
layoutItem.measure(); 
msnry.layoutItems([layoutItem], true);

В этом примере:

  1. Создаётся Masonry сетка.
  2. Новый элемент добавляется в контейнер.
  3. Создаётся layoutItem для нового блока.
  4. Метод measure() обновляет размеры.
  5. layoutItems() размещает элемент мгновенно без анимации (isInstant: true).

Ключевые моменты

  • layout управляет всей сеткой, хранит состояние колонок и массив layoutItems.
  • layoutItem инкапсулирует каждый блок, предоставляя методы для измерения и позиционирования.
  • Связка layout + layoutItem обеспечивает корректное, динамическое и анимированное расположение элементов.
  • Методы layoutItems, measure, applyPosition и transitionTo позволяют гибко управлять сеткой и оптимизировать производительность при динамическом контенте.

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