Библиотека Masonry использует событийную модель для уведомления о завершении различных внутренних операций. События позволяют отслеживать изменения состояния сетки, реагировать на перерасчёт позиций элементов и выполнять дополнительные действия после завершения раскладки.
Система событий реализована через зависимость от библиотеки EvEmitter. Благодаря этому Masonry поддерживает простой и предсказуемый интерфейс подписки и обработки событий.
Основная цель событий — предоставить разработчику точку расширения логики после выполнения ключевых операций, таких как:
Событие 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 вызывается после удаления
элементов из сетки.
msnry.on('removeComplete', function(items) {
console.log('Removed ' + items.length + ' items');
});
Аргумент items содержит список удалённых элементов.
Это событие используется при динамическом изменении содержимого интерфейса, например:
Подписка на события выполняется методом on.
Сигнатура метода:
masonryInstance.on(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');
});
Последовательность работы:
layoutComplete.Раскладка элементов может зависеть от фактических размеров изображений. До их загрузки размеры блоков могут быть неизвестны.
Для корректной работы часто используется библиотека imagesLoaded.
Пример:
imagesLoaded('.grid', function() {
msnry.layout();
});
msnry.on('layoutComplete', function() {
console.log('Layout recalculated after images loaded');
});
Последовательность:
Обработчики событий получают аргументы, содержащие информацию о текущем действии.
Например:
msnry.on('layoutComplete', function(items) {
items.forEach(function(item) {
console.log(item.element);
});
});
Каждый объект item представляет внутреннюю структуру
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 часто используются совместно с библиотеками интерфейсной анимации, такими как:
Пример:
msnry.on('layoutComplete', function(items) {
items.forEach(function(item) {
gsap.from(item.element, {
opacity: 0,
y: 30,
duration: 0.4
});
});
});
Типичный жизненный цикл событий выглядит следующим образом:
layoutComplete;При последующих изменениях сетки этот цикл повторяется.