initLayout

Параметр initLayout управляет автоматическим запуском первичного размещения элементов в момент инициализации экземпляра библиотеки Packery. По умолчанию Packery сразу после создания объекта вычисляет позиции всех элементов сетки и выполняет компоновку. Параметр initLayout позволяет отключить это поведение и получить полный контроль над моментом запуска алгоритма размещения.

Это особенно полезно в ситуациях, когда элементы контейнера ещё не полностью подготовлены: например, изображения не загружены, размеры блоков изменяются динамически или требуется предварительная обработка DOM.


Поведение по умолчанию

По умолчанию значение initLayout установлено в true. Это означает, что после создания экземпляра Packery автоматически выполняется метод layout().

var grid = new Packery('.grid', {
  itemSelector: '.grid-item'
});

Последовательность действий при стандартной инициализации:

  1. Поиск контейнера.
  2. Определение всех элементов, соответствующих itemSelector.
  3. Расчёт размеров контейнера и элементов.
  4. Вычисление позиций.
  5. Размещение элементов внутри контейнера.

Всё происходит автоматически, без необходимости дополнительных вызовов методов.


Отключение автоматического layout

Для отключения первичного размещения используется параметр:

initLayout: false

Пример:

var grid = new Packery('.grid', {
  itemSelector: '.grid-item',
  initLayout: false
});

В этом случае:

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

Фактически Packery находится в состоянии ожидания.


Ручной запуск компоновки

После отключения автоматической инициализации необходимо самостоятельно вызвать метод layout().

grid.layout();

Полный пример:

var grid = new Packery('.grid', {
  itemSelector: '.grid-item',
  initLayout: false
});

// подготовка данных или загрузка ресурсов

grid.layout();

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


Практическое применение

Ожидание загрузки изображений

Одной из наиболее распространённых проблем при работе с сетками является изменение размеров элементов после загрузки изображений. Если layout выполнится до загрузки изображений, размеры блоков могут измениться, что приведёт к неправильной компоновке.

Использование initLayout: false позволяет сначала дождаться загрузки всех изображений.

var grid = new Packery('.grid', {
  itemSelector: '.grid-item',
  initLayout: false
});

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

Алгоритм работы:

  1. Packery инициализируется без запуска layout.
  2. библиотека imagesLoaded отслеживает загрузку всех изображений.
  3. после загрузки выполняется layout().

Это гарантирует корректные размеры элементов.


Асинхронная загрузка данных

При получении элементов из API или при динамической генерации DOM структура сетки может формироваться постепенно.

var grid = new Packery('.grid', {
  itemSelector: '.grid-item',
  initLayout: false
});

fetch('/api/items')
  .then(response => response.json())
  .then(data => {
    renderItems(data);
    grid.reloadItems();
    grid.layout();
  });

Последовательность:

  1. данные загружаются с сервера;
  2. элементы добавляются в DOM;
  3. Packery обновляет список элементов (reloadItems);
  4. выполняется layout.

Предварительная модификация элементов

Иногда требуется изменить размеры или классы элементов перед размещением.

var grid = new Packery('.grid', {
  itemSelector: '.grid-item',
  initLayout: false
});

var items = document.querySelectorAll('.grid-item');

items.forEach(function(item) {
  if (item.dataset.size === 'large') {
    item.classList.add('grid-item--large');
  }
});

grid.layout();

Преимущество такого подхода заключается в том, что layout выполняется только после завершения всех модификаций.


Взаимодействие с другими методами Packery

reloadItems()

Метод reloadItems() заставляет Packery заново собрать список элементов внутри контейнера.

При использовании initLayout: false последовательность обычно выглядит следующим образом:

grid.reloadItems();
grid.layout();

appended()

Если новые элементы добавляются после первоначальной инициализации:

var newItems = document.querySelectorAll('.new-items');

grid.appended(newItems);
grid.layout();

Хотя метод appended() может сам инициировать перерасчёт, при отключённом initLayout важно контролировать порядок вызовов.


layout()

Метод layout() является центральным механизмом запуска алгоритма размещения.

При initLayout: false он становится обязательным шагом.

grid.layout();

Каждый вызов:

  • пересчитывает позиции элементов
  • обновляет координаты
  • применяет CSS-трансформации

Жизненный цикл экземпляра Packery при initLayout: false

  1. Создание объекта Packery.
  2. Регистрация элементов.
  3. Отсутствие вычисления позиций.
  4. Подготовка DOM или данных.
  5. Ручной запуск layout().

Такой жизненный цикл позволяет встроить Packery в сложные сценарии инициализации.


Влияние на производительность

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

Использование initLayout: false позволяет:

  • предотвратить лишние перерасчёты,
  • сократить количество операций layout,
  • улучшить время начальной загрузки.

Особенно это заметно при:

  • динамическом добавлении большого количества элементов,
  • серверном рендеринге,
  • сложных интерфейсах с несколькими сетками.

Сравнение поведения

Параметр Поведение
initLayout: true Layout запускается автоматически
initLayout: false Layout запускается вручную

Комбинирование с событиями

Packery генерирует события, связанные с процессом размещения. После ручного запуска layout можно отслеживать завершение компоновки.

grid.on('layoutComplete', function(items) {
  console.log('Layout завершён');
});

Пример последовательности:

var grid = new Packery('.grid', {
  itemSelector: '.grid-item',
  initLayout: false
});

prepareGrid();

grid.layout();

После выполнения layout() будет сгенерировано событие layoutComplete.


Использование с несколькими сетками

При наличии нескольких контейнеров Packery можно синхронизировать их инициализацию.

var grids = document.querySelectorAll('.grid');

var instances = [];

grids.forEach(function(gridElement) {
  var pckry = new Packery(gridElement, {
    itemSelector: '.grid-item',
    initLayout: false
  });

  instances.push(pckry);
});

// после подготовки всех данных

instances.forEach(function(instance) {
  instance.layout();
});

Это предотвращает ситуации, когда разные сетки начинают размещение в разные моменты времени.


Типичные ошибки

Отсутствие вызова layout()

Если initLayout отключён, но layout() не вызывается, элементы остаются в исходных позициях DOM и не получают координат Packery.

Признаки:

  • элементы накладываются друг на друга
  • сетка выглядит неорганизованной

Вызов layout() до подготовки элементов

Если layout вызывается слишком рано:

grid.layout();
loadImages();

после загрузки изображений размеры блоков изменятся, что может нарушить структуру сетки.


Неправильный порядок методов

Корректный порядок:

renderItems();
grid.reloadItems();
grid.layout();

Некорректный порядок:

grid.layout();
grid.reloadItems();

Во втором случае новые элементы не будут учтены при размещении.


Когда использование initLayout: false оправдано

Отключение автоматического layout применяется в следующих случаях:

  • асинхронная загрузка контента
  • ожидание загрузки изображений
  • динамическая генерация DOM
  • предварительное изменение размеров элементов
  • оптимизация производительности при большом количестве элементов
  • сложная последовательность инициализации интерфейса

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