Работа с коллекциями элементов

Библиотека Muuri строит интерфейс вокруг управляемой коллекции элементов — объектов, представляющих DOM-узлы, размещённые в сетке. Каждый элемент сетки инкапсулируется во внутренний объект Item, который хранит состояние, позицию, размеры, DOM-ссылки и служебную информацию.

Коллекции элементов используются для:

  • управления структурой сетки
  • динамического добавления и удаления элементов
  • фильтрации и сортировки
  • перемещения элементов внутри или между сетками
  • массовых операций над группами элементов

Работа с коллекциями является ключевой частью архитектуры Muuri, поскольку сетка фактически представляет собой управляемый массив Item.


Внутреннее представление элементов

После инициализации сетки:

const grid = new Muuri('.grid');

каждый дочерний элемент контейнера превращается во внутренний объект Item.

Структура такого объекта включает:

  • ссылку на DOM-элемент
  • состояние видимости
  • позицию в сетке
  • размеры
  • индексы
  • состояние перетаскивания
  • флаги анимации

Muuri хранит элементы во внутреннем массиве:

grid._items

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


Получение элементов сетки

Метод getItems()

Основной способ получения коллекции элементов.

const items = grid.getItems();

Возвращается массив объектов Item.

Каждый элемент содержит методы:

  • getElement()
  • getWidth()
  • getHeight()
  • isActive()
  • isVisible()

Пример получения DOM-узлов:

const elements = grid.getItems().map(item => item.getElement());

Получение элемента по DOM-узлу

Если известен DOM-элемент:

const element = document.querySelector('.item');
const item = grid.getItem(element);

Muuri сопоставляет DOM-элемент с внутренним объектом Item.


Получение элементов по индексу

const firstItem = grid.getItems()[0];

Muuri поддерживает порядок элементов в массиве, соответствующий их текущему порядку в сетке.


Получение нескольких элементов

Метод getItems() может принимать аргументы:

grid.getItems(elements);
grid.getItems([element1, element2]);

Пример:

const selected = grid.getItems([
  document.querySelector('#item1'),
  document.querySelector('#item2')
]);

Возвращается массив соответствующих Item.


Добавление элементов в коллекцию

Muuri позволяет динамически расширять коллекцию.

Метод add()

grid.add(element);

Пример:

const newItem = document.createElement('div');
newItem.className = 'item';

grid.add(newItem);

Элемент автоматически:

  1. добавляется в DOM
  2. превращается в Item
  3. включается в коллекцию
  4. получает позицию в сетке

Добавление нескольких элементов

grid.add([element1, element2, element3]);

Пример:

const elements = [];

for (let i = 0; i < 5; i++) {
  const el = document.createElement('div');
  el.className = 'item';
  elements.push(el);
}

grid.add(elements);

Параметры метода add

Метод принимает объект настроек:

grid.add(elements, {
  index: 2,
  active: true
});

Параметры:

Параметр Назначение
index позиция вставки
active активность элемента
layout выполнить ли перерасчет сетки

Пример:

grid.add(newItem, {
  index: 0
});

Элемент будет вставлен в начало коллекции.


Удаление элементов

Удаление производится методом remove().

Базовый пример

const item = grid.getItems()[0];
grid.remove(item);

Muuri:

  1. удаляет элемент из коллекции
  2. удаляет его из DOM
  3. пересчитывает сетку

Удаление нескольких элементов

const items = grid.getItems().slice(0, 3);

grid.remove(items);

Удаление без удаления из DOM

Иногда требуется удалить элемент только из сетки.

grid.remove(item, { removeElements: false });

Теперь элемент:

  • исчезнет из коллекции
  • останется в DOM

Перемещение элементов внутри коллекции

Muuri позволяет изменять порядок элементов.

Метод move()

grid.move(item, newIndex);

Пример:

const item = grid.getItems()[3];

grid.move(item, 0);

Элемент переместится в начало массива.


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

grid.move(items, index);

Пример:

const items = grid.getItems().slice(0, 2);

grid.move(items, 5);

Перемещение относительно другого элемента

grid.move(itemA, itemB);

itemA будет перемещен на позицию itemB.


Обмен позициями

Иногда требуется поменять элементы местами.

Muuri поддерживает режим swap.

grid.move(itemA, itemB, {
  action: 'swap'
});

Теперь:

  • itemA занимает позицию itemB
  • itemB занимает позицию itemA

Фильтрация коллекций

Muuri может скрывать элементы без удаления.

Метод filter()

grid.filter(selector);

Пример:

grid.filter('.category-a');

Показываются только элементы с классом category-a.


Фильтрация функцией

grid.filter(item => {
  const element = item.getElement();
  return element.dataset.type === 'fruit';
});

Функция должна вернуть:

  • true — элемент остается
  • false — элемент скрывается

Сброс фильтра

grid.filter(() => true);

Все элементы становятся видимыми.


Сортировка коллекции

Muuri позволяет сортировать элементы.

Метод sort()

grid.sort(compareFunction);

Пример:

grid.sort((a, b) => {
  const aValue = a.getElement().dataset.price;
  const bValue = b.getElement().dataset.price;

  return aValue - bValue;
});

Сортировка по атрибутам

grid.sort((a, b) => {
  return a.getElement().textContent.localeCompare(
    b.getElement().textContent
  );
});

Сортировка по нескольким критериям

grid.sort((a, b) => {
  const priceA = +a.getElement().dataset.price;
  const priceB = +b.getElement().dataset.price;

  if (priceA !== priceB) {
    return priceA - priceB;
  }

  const nameA = a.getElement().dataset.name;
  const nameB = b.getElement().dataset.name;

  return nameA.localeCompare(nameB);
});

Получение активных элементов

Muuri различает активные и скрытые элементы.

Получение активных:

const activeItems = grid.getItems().filter(item => item.isActive());

Работа с видимостью элементов

Показ элементов

grid.show(items);

Пример:

grid.show(grid.getItems().slice(0, 3));

Скрытие элементов

grid.hide(items);

Пример:

grid.hide(grid.getItems().slice(3, 6));

Элементы остаются в коллекции, но исключаются из расчета сетки.


Перенос элементов между сетками

Muuri поддерживает несколько сеток.

const gridA = new Muuri('.grid-a');
const gridB = new Muuri('.grid-b');

Перемещение:

const item = gridA.getItems()[0];

gridB.add(item.getElement());
gridA.remove(item, { removeElements: false });

Элемент переносится между коллекциями.


Массовые операции с коллекциями

Muuri оптимизирован для пакетных изменений.

Пример:

const items = grid.getItems();

items.forEach(item => {
  item.getElement().classList.add('updated');
});

grid.refreshItems().layout();

Методы:

  • refreshItems() — обновление размеров
  • layout() — перерасчет позиций

Обновление размеров элементов

Если содержимое изменилось:

grid.refreshItems();
grid.layout();

Или одной цепочкой:

grid.refreshItems().layout();

Итерация по коллекции

Коллекции Muuri являются обычными массивами.

Используются стандартные методы:

forEach

grid.getItems().forEach(item => {
  console.log(item.getElement());
});

map

const ids = grid.getItems().map(item =>
  item.getElement().id
);

filter

const largeItems = grid.getItems().filter(item =>
  item.getWidth() > 200
);

Получение размеров элементов

Каждый Item предоставляет методы размеров:

item.getWidth();
item.getHeight();
item.getMargin();

Пример:

grid.getItems().forEach(item => {
  console.log(item.getWidth(), item.getHeight());
});

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

Muuri предоставляет методы состояния:

item.isVisible();
item.isActive();
item.isDragging();
item.isPositioning();

Пример:

const dragging = grid.getItems().filter(item =>
  item.isDragging()
);

Полное обновление коллекции

Если DOM изменился вне Muuri:

grid.synchronize();

Метод:

  • синхронизирует DOM и внутреннюю коллекцию
  • добавляет новые элементы
  • удаляет отсутствующие

Очистка коллекции

Удаление всех элементов:

grid.remove(grid.getItems());

Альтернатива:

const items = grid.getItems();

items.forEach(item => {
  grid.remove(item);
});

Оптимизация операций с коллекциями

Для высокой производительности:

  1. Используется пакетная обработка
  2. Минимизируются вызовы layout()
  3. Обновления группируются

Оптимизированный пример:

const items = grid.getItems();

items.forEach(item => {
  item.getElement().classList.add('updated');
});

grid.refreshItems();
grid.layout();

Вместо повторного перерасчета после каждого изменения.


Архитектурная роль коллекций

Коллекции элементов в Muuri выполняют несколько функций:

  • управление DOM-структурой
  • хранение состояния интерфейса
  • управление позиционированием
  • связь между DOM и системой layout
  • поддержка drag-and-drop

Благодаря централизованной коллекции элементов библиотека обеспечивает:

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