once

Метод once используется для однократной подписки на событие внутри библиотеки Masonry. Он позволяет выполнить обработчик только один раз, после чего подписка автоматически удаляется. Такой подход особенно полезен при работе с жизненным циклом сетки: инициализации, завершении перерасчёта элементов, загрузке изображений или других событиях, которые должны обрабатываться единственный раз.

Внутри Masonry система событий реализована на базе библиотеки EvEmitter, которая обеспечивает простую модель подписки, отписки и вызова обработчиков. Метод once является частью этой системы.


Назначение метода

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

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

Основные сценарии использования:

  • выполнение кода после первого завершения раскладки (layoutComplete);
  • запуск логики после первой загрузки изображений;
  • единоразовая инициализация зависимых компонентов;
  • выполнение операций после первого появления элементов в сетке.

Сигнатура метода

msnry.once( eventName, listener )

Параметры

eventName

Строка с названием события Masonry.

Примеры событий:

  • layoutComplete
  • removeComplete
  • appendComplete

listener

Функция-обработчик события, которая будет вызвана только один раз.


Базовый пример использования

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

var msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: 200
});

msnry.once('layoutComplete', function(items) {
  console.log('Первый layout завершён');
});

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

  1. Создаётся экземпляр Masonry.
  2. Выполняется раскладка элементов.
  3. После завершения первой раскладки вызывается обработчик.
  4. После выполнения обработчик автоматически удаляется.

Если сетка будет перерасчитана повторно, обработчик больше не сработает.


Отличие once от on

Система событий Masonry содержит два основных метода подписки:

Метод Поведение
on обработчик вызывается каждый раз, когда происходит событие
once обработчик вызывается только один раз

Пример с on

msnry.on('layoutComplete', function() {
  console.log('layout выполнен');
});

При каждом перерасчёте сетки сообщение будет выводиться снова.

Пример с once

msnry.once('layoutComplete', function() {
  console.log('layout выполнен один раз');
});

Сообщение появится только при первом завершении layout.


Механизм работы

Метод once реализуется через внутренний механизм обёртки обработчика.

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

  1. пользователь передаёт обработчик события;
  2. Masonry создаёт внутреннюю функцию-обёртку;
  3. обёртка вызывает оригинальный обработчик;
  4. сразу после выполнения происходит автоматическая отписка.

Упрощённая схема реализации:

once(eventName, listener) {
  function onceListener() {
    listener.apply(this, arguments);
    this.off(eventName, onceListener);
  }

  this.on(eventName, onceListener);
}

Таким образом:

  • обработчик срабатывает один раз;
  • после выполнения удаляется из массива слушателей.

Использование с событием layoutComplete

Событие layoutComplete является одним из самых часто используемых событий Masonry. Оно срабатывает после завершения вычисления позиций всех элементов сетки.

Пример однократной реакции на завершение layout:

msnry.once('layoutComplete', function(items) {
  console.log('Количество элементов:', items.length);
});

Аргумент items содержит массив объектов Masonry, представляющих элементы сетки.


Использование при динамической загрузке элементов

При добавлении элементов через append или appended может потребоваться выполнить действие только после первой вставки элементов.

msnry.once('appendComplete', function(items) {
  console.log('Первые элементы добавлены');
});

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


Применение при инициализации интерфейса

В сложных интерфейсах Masonry может выступать зависимостью для других компонентов. Например, галереи изображений или анимационных библиотек.

Однократная подписка позволяет выполнить код только после первой готовности сетки.

msnry.once('layoutComplete', function() {
  initLightbox();
});

Это гарантирует, что сторонний компонент инициализируется после расчёта позиций элементов.


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

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

В таком случае once применяется для запуска layout только после первого события загрузки.

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

Такой подход предотвращает повторный запуск layout на каждое изображение.


Передача данных обработчику

Некоторые события Masonry передают данные в обработчик.

Например:

msnry.once('removeComplete', function(items) {
  console.log('Удалено элементов:', items.length);
});

Параметр items представляет массив удалённых элементов.


Использование стрелочных функций

Метод once поддерживает современные синтаксические возможности JavaScript.

msnry.once('layoutComplete', (items) => {
  console.log('layout завершён', items);
});

Однако важно учитывать особенности контекста this. В стрелочных функциях он не привязывается к экземпляру Masonry.

Если требуется доступ к экземпляру через this, следует использовать обычную функцию.

msnry.once('layoutComplete', function() {
  console.log(this);
});

Сочетание once и off

Несмотря на автоматическую отписку, once можно отменить вручную до момента выполнения.

function handler() {
  console.log('выполнится один раз');
}

msnry.once('layoutComplete', handler);

msnry.off('layoutComplete', handler);

После вызова off обработчик не будет выполнен.


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

1. Неправильное название события

msnry.once('layoutcomplete', handler);

События чувствительны к регистру. Правильное название:

layoutComplete

2. Подписка после события

Если событие уже произошло, once не вызовет обработчик.

Например:

msnry.layout();

msnry.once('layoutComplete', handler);

В этом случае обработчик может не выполниться.


3. Повторная регистрация

Каждый вызов once создаёт новый обработчик.

msnry.once('layoutComplete', handler);
msnry.once('layoutComplete', handler);

В результате функция будет выполнена два раза, но каждая подписка — только один раз.


Практический сценарий: первая готовность сетки

Частая задача — скрыть loader после первой раскладки.

var loader = document.querySelector('.loader');

msnry.once('layoutComplete', function() {
  loader.style.display = 'none';
});

Алгоритм:

  1. страница загружает элементы;
  2. Masonry рассчитывает позиции;
  3. событие layoutComplete происходит;
  4. loader скрывается.

Повторные пересчёты сетки не вызывают обработчик.


Роль once в архитектуре событий Masonry

Метод once обеспечивает:

  • безопасное управление событиями
  • предотвращение дублирования логики
  • снижение риска утечек памяти
  • более чистую структуру кода

В крупных приложениях это особенно важно, поскольку количество событий может быстро расти.

Однократные подписки позволяют точно контролировать жизненный цикл интерфейса и избегать избыточных обработчиков.