Обработка событий удаления

Masonry — это библиотека для создания динамических сеток с “кирпичной” компоновкой элементов. Одним из важных аспектов работы с Masonry является управление удалением элементов и корректная переразметка сетки после этих действий. Обработка событий удаления позволяет поддерживать визуальную целостность и стабильное расположение элементов.


Методы удаления элементов

Masonry предоставляет несколько способов удаления элементов:

  1. Метод remove
const grid = document.querySelector('.grid');
const masonryInstance = new Masonry(grid, {
  itemSelector: '.grid-item'
});

const itemToRemove = document.querySelector('.grid-item:nth-child(2)');
masonryInstance.remove(itemToRemove);
masonryInstance.layout();
  • Метод remove удаляет элемент из DOM и из внутренней структуры Masonry.
  • После удаления необходимо вызвать метод layout, чтобы сетка перераспределила оставшиеся элементы.
  • Если одновременно удаляется несколько элементов, их можно передать в массив.
const itemsToRemove = document.querySelectorAll('.grid-item.to-remove');
masonryInstance.remove(itemsToRemove);
masonryInstance.layout();

События, связанные с удалением

Masonry генерирует события, которые можно использовать для управления удалением элементов:

  • removeComplete — срабатывает после того, как элемент был полностью удален и сетка перераспределена.
  • layoutComplete — срабатывает после любой переразметки сетки, включая удаление элементов.

Пример использования:

masonryInstance.on('removeComplete', function(removedItems) {
  console.log('Элементы удалены:', removedItems);
});

masonryInstance.on('layoutComplete', function(laidOutItems) {
  console.log('Сетка обновлена после удаления:', laidOutItems);
});
  • Параметр removedItems содержит массив DOM-элементов, которые были удалены.
  • laidOutItems содержит массив элементов, участвовавших в переразметке.

Анимация удаления

Для плавного визуального эффекта удаления элементов можно использовать CSS-переходы совместно с Masonry:

.grid-item {
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.grid-item.removing {
  opacity: 0;
  transform: scale(0.5);
}
const item = document.querySelector('.grid-item:nth-child(1)');
item.classList.add('removing');

item.addEventListener('transitionend', () => {
  masonryInstance.remove(item);
  masonryInstance.layout();
});
  • Класс .removing запускает анимацию.
  • После окончания анимации элемент удаляется из DOM, и Masonry перераспределяет сетку.

Удаление элементов с задержкой

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

const items = document.querySelectorAll('.grid-item.to-remove');
items.forEach((item, index) => {
  setTimeout(() => {
    item.classList.add('removing');
    item.addEventListener('transitionend', () => {
      masonryInstance.remove(item);
      masonryInstance.layout();
    });
  }, index * 200);
});
  • Используется метод setTimeout для последовательного запуска анимации удаления.
  • Masonry корректно перераспределяет сетку после каждого удаления.

Интеграция с динамическим контентом

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

function removeElement(item) {
  item.classList.add('removing');
  item.addEventListener('transitionend', () => {
    masonryInstance.remove(item);
    masonryInstance.layout();
  });
}

// Пример: удаление по клику
document.querySelector('.grid').addEventListener('click', (e) => {
  if (e.target.matches('.grid-item .delete-btn')) {
    const item = e.target.closest('.grid-item');
    removeElement(item);
  }
});
  • Метод removeElement унифицирует процесс удаления с анимацией.
  • При динамическом добавлении новых элементов достаточно вызвать masonryInstance.appended(newItem) для корректного учета сеткой.

Оптимизация при массовом удалении

При удалении большого количества элементов одновременно важно минимизировать количество перерасчетов сетки:

const itemsToRemove = document.querySelectorAll('.grid-item.to-remove');
itemsToRemove.forEach(item => item.classList.add('removing'));

Promise.all(Array.from(itemsToRemove).map(item => new Promise(resolve => {
  item.addEventListener('transitionend', resolve);
}))).then(() => {
  masonryInstance.remove(itemsToRemove);
  masonryInstance.layout();
});
  • Все анимации запускаются одновременно.
  • Сетка перераспределяется один раз после завершения всех анимаций, что улучшает производительность.

Важные моменты

  • Обязателен вызов layout после удаления — без него Masonry не обновит позиции оставшихся элементов.
  • События можно использовать для синхронизации с другими UI-компонентами — например, счетчиками или фильтрами.
  • Удаление должно учитывать CSS-переходы для плавной анимации без “рывков”.
  • Массовое удаление через массив элементов всегда эффективнее последовательного вызова remove для каждого элемента по отдельности.