Пакетные операции

Muuri — это библиотека для организации сетки элементов с динамическим расположением и анимацией. Пакетные операции в Muuri позволяют одновременно управлять группой элементов, что значительно повышает производительность и упрощает код при работе с большими сетками. Ключевой принцип заключается в том, что Muuri позволяет применять действия к множеству элементов сразу, вместо обработки каждого элемента по отдельности.

Выбор группы элементов

Для выполнения пакетных операций сначала необходимо определить набор элементов, с которыми будет производиться работа. Muuri предоставляет несколько методов для выбора элементов:

  • getItems() — возвращает массив всех элементов сетки.
  • getItems(selector) — возвращает элементы по CSS-селектору.
  • filter(predicate) — позволяет отфильтровать элементы на основе функции-предиката.

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

const allItems = grid.getItems(); // все элементы
const activeItems = grid.getItems().filter(item => item.getElement().classList.contains('active'));

Фильтрация через предикат особенно полезна для динамического управления состояниями элементов без необходимости повторного рендеринга всей сетки.

Добавление и удаление элементов пакетно

Для динамических интерфейсов часто требуется добавлять или удалять несколько элементов одновременно. Muuri предоставляет методы add() и remove() для этих целей:

  • add(elements, options) — добавляет один или несколько элементов в сетку. Можно передать массив DOM-элементов и объект опций, где задаются начальные координаты, видимость и анимация.
  • remove(items, options) — удаляет элементы из сетки с возможностью анимированного исчезновения.

Пример пакетного добавления:

const newElements = document.querySelectorAll('.new-item');
grid.add(newElements, { layout: 'instant' });

Пример пакетного удаления:

const itemsToRemove = grid.getItems().filter(item => item.isActive());
grid.remove(itemsToRemove, { removeElements: true, layout: 'animate' });

Важно: параметр removeElements: true удаляет элементы из DOM полностью, иначе они остаются в документе, но исключаются из сетки.

Перемещение и сортировка элементов

Muuri поддерживает групповые операции перемещения и сортировки элементов:

  • sort(comparator, options) — сортировка элементов по пользовательской функции. Можно задать опции анимации и пересчета макета.
  • swap(item1, item2, options) — замена местами двух элементов, которую также можно анимировать.

Пример сортировки по пользовательскому атрибуту data-order:

grid.sort((a, b) => {
  return a.getElement().dataset.order - b.getElement().dataset.order;
}, { layout: 'animate' });

Фильтрация и скрытие элементов

Для управления видимостью группы элементов используется метод filter(), который работает как предикат, возвращающий true для видимых элементов и false для скрытых:

grid.filter(item => item.getElement().classList.contains('highlight'));

В результате элементы, не удовлетворяющие условию, анимированно скрываются, а оставшиеся перестраиваются на сетке. Опции фильтра позволяют контролировать анимацию и пересчет макета (layout: 'instant' | 'animate').

Пакетное обновление контента и стилей

Muuri позволяет обновлять несколько элементов одновременно без полной перестройки сетки:

  • refreshItems(items) — пересчитывает размеры и положение выбранных элементов.
  • updateItem(item, options) — обновляет свойства отдельного элемента (позиция, видимость, стиль) с возможностью пакетного вызова через цикл.

Пример пакетного обновления:

const itemsToRefresh = grid.getItems().filter(item => item.needsUpdate);
grid.refreshItems(itemsToRefresh);
grid.layout();

Метод refreshItems особенно важен при динамическом изменении контента, чтобы избежать мерцания и некорректного позиционирования элементов.

Анимация пакетных операций

Muuri поддерживает плавную анимацию всех пакетных операций. Настройка параметров анимации осуществляется через объект опций:

  • duration — время анимации в миллисекундах
  • easing — функция интерполяции (например, 'ease', 'ease-in-out')
  • layout — определяет, как обновляется сетка: 'instant' или 'animate'

Пример пакетного перемещения с анимацией:

grid.sort((a, b) => a.getElement().dataset.priority - b.getElement().dataset.priority, {
  layout: 'animate',
  duration: 400,
  easing: 'ease-in-out'
});

Оптимизация пакетных операций

  • Сбор изменений перед layout() — вызовы add, remove, refreshItems можно сгруппировать и выполнить один раз grid.layout(), чтобы уменьшить количество пересчетов.
  • Фильтрация до операций — предварительное определение элементов для добавления или удаления снижает нагрузку на рендер.
  • Использование layout: 'instant' при массовом обновлении — ускоряет работу при создании или перезаписи сетки, а финальную анимацию можно запускать отдельно.

Эти подходы позволяют поддерживать плавность интерфейса даже при работе с сотнями элементов одновременно.

Взаимодействие с событиями

Muuri генерирует события на уровне сетки и элементов, что полезно при пакетных операциях:

  • move, add, remove, layoutStart, layoutEnd
  • Подписка на события позволяет отслеживать завершение анимации всех пакетных действий:
grid.on('layoutEnd', () => {
  console.log('Все элементы обновлены и расположены');
});

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