Подписка на события

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

Система событий реализована через зависимость от библиотеки EvEmitter. Благодаря этому Masonry поддерживает простой и предсказуемый интерфейс подписки и обработки событий.

Основная цель событий — предоставить разработчику точку расширения логики после выполнения ключевых операций, таких как:

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

Основные события Masonry

layoutComplete

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

Это событие особенно важно при:

  • инициализации сетки;
  • вызове метода layout();
  • добавлении новых элементов;
  • перерасчёте после изменения размеров контейнера.

Пример подписки:

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

msnry.on('layoutComplete', function(items) {
  console.log('Layout completed for ' + items.length + ' items');
});

Параметр items содержит массив элементов, участвующих в текущем процессе раскладки.

Типичная область применения:

  • запуск анимаций после построения сетки;
  • отложенная загрузка изображений;
  • обновление пользовательского интерфейса.

removeComplete

Событие removeComplete вызывается после удаления элементов из сетки.

msnry.on('removeComplete', function(items) {
  console.log('Removed ' + items.length + ' items');
});

Аргумент items содержит список удалённых элементов.

Это событие используется при динамическом изменении содержимого интерфейса, например:

  • удаление карточек товаров;
  • очистка галереи;
  • фильтрация контента.

Подписка на события

Подписка на события выполняется методом on.

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

masonryInstance.on(eventName, listener)

Параметры:

  • eventName — строка с названием события;
  • listener — функция-обработчик.

Пример:

msnry.on('layoutComplete', function(items) {
  console.log('Layout finished');
});

Каждый раз при возникновении события вызывается переданный обработчик.


Отписка от событий

Для удаления обработчика используется метод off.

Сигнатура:

masonryInstance.off(eventName, listener)

Пример:

function onLayout(items) {
  console.log('layout finished');
}

msnry.on('layoutComplete', onLayout);

// позже
msnry.off('layoutComplete', onLayout);

Удаление обработчиков важно для:

  • предотвращения утечек памяти;
  • корректной очистки логики при уничтожении компонентов;
  • управления жизненным циклом интерфейса.

Однократная подписка

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

msnry.once('layoutComplete', function(items) {
  console.log('Initial layout finished');
});

После первого вызова обработчик автоматически удаляется.

Подход полезен в ситуациях:

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

События при добавлении элементов

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

Пример:

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

msnry.appended(newItems);

msnry.once('layoutComplete', function(items) {
  console.log('New elements positioned');
});

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

  1. новые элементы добавляются в DOM;
  2. Masonry получает список элементов;
  3. выполняется перерасчёт сетки;
  4. после завершения вызывается layoutComplete.

Синхронизация с загрузкой изображений

Раскладка элементов может зависеть от фактических размеров изображений. До их загрузки размеры блоков могут быть неизвестны.

Для корректной работы часто используется библиотека imagesLoaded.

Пример:

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

msnry.on('layoutComplete', function() {
  console.log('Layout recalculated after images loaded');
});

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

  1. происходит загрузка изображений;
  2. вызывается перерасчёт сетки;
  3. событие сообщает о завершении процесса.

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

Обработчики событий получают аргументы, содержащие информацию о текущем действии.

Например:

msnry.on('layoutComplete', function(items) {
  items.forEach(function(item) {
    console.log(item.element);
  });
});

Каждый объект item представляет внутреннюю структуру Masonry, содержащую:

  • DOM-элемент;
  • координаты;
  • размеры;
  • состояние позиционирования.

Это позволяет:

  • анализировать расположение элементов;
  • создавать дополнительные эффекты;
  • интегрировать Masonry с другими компонентами интерфейса.

Несколько обработчиков одного события

Одно событие может иметь несколько подписчиков.

msnry.on('layoutComplete', handlerA);
msnry.on('layoutComplete', handlerB);
msnry.on('layoutComplete', handlerC);

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

Такой подход используется при разделении логики на независимые модули:

  • анимация интерфейса;
  • аналитика;
  • загрузка дополнительного контента;
  • обновление пользовательского состояния.

Организация обработчиков в архитектуре приложения

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

Пример структуры:

grid/
 ├─ gridInit.js
 ├─ gridEvents.js
 ├─ gridItems.js
 └─ gridAnimations.js

Файл обработки событий:

export function bindGridEvents(msnry) {
  msnry.on('layoutComplete', handleLayout);
  msnry.on('removeComplete', handleRemove);
}

function handleLayout(items) {
  console.log('layout finished');
}

function handleRemove(items) {
  console.log('items removed');
}

Такой подход обеспечивает:

  • изоляцию логики;
  • удобство тестирования;
  • масштабируемость архитектуры.

Комбинирование событий с пользовательскими событиями

Иногда события Masonry используются как триггер для запуска собственных событий приложения.

Пример:

msnry.on('layoutComplete', function(items) {
  document.dispatchEvent(
    new CustomEvent('grid:layoutComplete', {
      detail: { items }
    })
  );
});

Теперь другие модули могут подписываться на событие приложения:

document.addEventListener('grid:layoutComplete', function(e) {
  console.log(e.detail.items);
});

Так создаётся единая система событий в приложении.


Очистка обработчиков при уничтожении сетки

При удалении сетки или переходе между страницами необходимо удалять обработчики.

msnry.off('layoutComplete', handleLayout);
msnry.off('removeComplete', handleRemove);

Если используется фреймворк, например React или Vue.js, отписка обычно выполняется на этапе уничтожения компонента.


Типичные сценарии использования событий

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

1. Анимация появления элементов

После завершения раскладки:

msnry.on('layoutComplete', function(items) {
  items.forEach(function(item) {
    item.element.classList.add('visible');
  });
});

2. Ленивая загрузка контента

При достижении определённого состояния сетки:

msnry.on('layoutComplete', function(items) {
  if (items.length < 10) {
    loadMoreContent();
  }
});

3. Синхронизация с другими интерфейсными компонентами

Например, обновление индикатора загрузки:

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

Особенности производительности

Частые события раскладки могут вызывать большое количество обработчиков. Для оптимизации рекомендуется:

  • минимизировать тяжёлые операции внутри обработчиков;
  • использовать once при необходимости одноразовой логики;
  • группировать операции.

Плохой пример:

msnry.on('layoutComplete', function() {
  heavyCalculation();
});

Лучший вариант:

msnry.once('layoutComplete', initializeLayout);

или

msnry.on('layoutComplete', debounce(updateUI, 100));

Взаимодействие с другими библиотеками

События Masonry часто используются совместно с библиотеками интерфейсной анимации, такими как:

  • GSAP
  • Anime.js

Пример:

msnry.on('layoutComplete', function(items) {
  items.forEach(function(item) {
    gsap.from(item.element, {
      opacity: 0,
      y: 30,
      duration: 0.4
    });
  });
});

Жизненный цикл событий Masonry

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

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

При последующих изменениях сетки этот цикл повторяется.