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

Packery — это библиотека для построения динамических сеток на основе drag-and-drop и masonry-подобного расположения элементов. Одним из ключевых аспектов управления сеткой является работа с событиями. Packery предоставляет мощный механизм для подписки и отписки от событий, что позволяет гибко управлять поведением элементов при их перемещении, добавлении или удалении.


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

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

  • layoutComplete — срабатывает после завершения перестройки сетки.
  • dragItemPositioned — возникает после того, как элемент был перемещён пользователем.
  • fitComplete — вызывается после того, как элемент успешно встроен в сетку методом fit.
  • removeComplete — срабатывает после удаления элементов из сетки.

Каждое событие можно привязать с помощью метода .on(eventName, handler).

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

pckry.on('layoutComplete', function(laidOutItems) {
  console.log('Сетка обновлена, количество элементов:', laidOutItems.length);
});

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

Для удаления обработчика используется метод .off(eventName, handler). Важно передавать ту же функцию, что была зарегистрирована, иначе отписка не произойдёт. Это позволяет предотвратить накопление лишних обработчиков и потенциальные утечки памяти.

function onDragPositioned(item) {
  console.log('Элемент перемещён:', item.element);
}

pckry.on('dragItemPositioned', onDragPositioned);

// Позже, когда обработчик больше не нужен
pckry.off('dragItemPositioned', onDragPositioned);

Особенности отписки

  1. Анонимные функции нельзя удалить напрямую.

    // Так не получится удалить
    pckry.on('layoutComplete', function() { console.log('Обновлено'); });
    pckry.off('layoutComplete', function() { console.log('Обновлено'); }); // Не сработает

    Для корректной отписки требуется сохранять ссылку на функцию.

  2. Удаление всех обработчиков события. Можно удалить все обработчики для конкретного события, передав только его название:

    pckry.off('layoutComplete');
  3. Удаление всех обработчиков всех событий.

    pckry.off();
  4. Контекст вызова обработчика Обработчики вызываются в контексте экземпляра Packery (this указывает на объект Packery), что позволяет использовать методы и свойства сетки внутри функции.


Примеры практического использования

Отписка после первого срабатывания

Иногда необходимо обработать событие только один раз. Для этого создаётся функция с последующей отпиской:

function onFitComplete(item) {
  console.log('Элемент встроен:', item.element);
  pckry.off('fitComplete', onFitComplete);
}

pckry.on('fitComplete', onFitComplete);

Удаление обработчиков при удалении элементов

Если элементы удаляются динамически, важно отписывать обработчики, чтобы не оставлять «висячие» ссылки:

function attachHandlers(item) {
  function onItemDragged() {
    console.log('Элемент перемещён:', item);
  }
  item.on('dragItemPositioned', onItemDragged);

  // Сохраняем ссылку для будущей отписки
  item._dragHandler = onItemDragged;
}

function removeItem(item) {
  if (item._dragHandler) {
    pckry.off('dragItemPositioned', item._dragHandler);
  }
  pckry.remove(item);
}

Рекомендации по управлению событиями

  • Сохранять ссылки на функции. Это обязательное условие для корректной отписки.
  • Удалять обработчики при удалении элементов. Позволяет избежать утечек памяти.
  • Использовать отписку для одноразовых событий. Повышает производительность при больших сетках.
  • Групповая отписка. Иногда удобнее удалить все обработчики сразу с помощью off() вместо удаления по отдельности.

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