Вложенные сетки

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

Основные принципы

Вложенная сетка представляет собой отдельный экземпляр Muuri, помещённый внутрь элемента родительской сетки. Родительская сетка управляет положением и анимацией контейнеров, а вложенная — элементами внутри этих контейнеров. Важно понимать, что Muuri не объединяет поведение вложенной и родительской сетки автоматически; каждая сетка работает автономно, но взаимодействие между ними может быть настроено через события.

Создание вложенной сетки

Структура HTML для вложенной сетки обычно выглядит следующим образом:

<div class="grid">
  <div class="item">
    <div class="item-content">
      <div class="nested-grid">
        <div class="nested-item">A</div>
        <div class="nested-item">B</div>
        <div class="nested-item">C</div>
      </div>
    </div>
  </div>
  <div class="item">
    <div class="item-content">
      <div class="nested-grid">
        <div class="nested-item">D</div>
        <div class="nested-item">E</div>
      </div>
    </div>
  </div>
</div>
  • .grid — контейнер родительской сетки.
  • .item — элементы родительской сетки.
  • .nested-grid — контейнер вложенной сетки.
  • .nested-item — элементы вложенной сетки.

Инициализация родительской и вложенной сетки

Инициализация выполняется по отдельности для каждой сетки:

const parentGrid = new Muuri('.grid', {
  dragEnabled: true,
  layoutDuration: 400,
  layoutEasing: 'ease'
});

document.querySelectorAll('.nested-grid').forEach((nestedGridEl) => {
  const nestedGrid = new Muuri(nestedGridEl, {
    dragEnabled: true,
    layoutDuration: 300,
    layoutEasing: 'ease-out'
  });
});

Каждая вложенная сетка получает свои параметры анимации и перетаскивания. Это позволяет настроить независимую динамику элементов внутри контейнера.

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

Muuri предоставляет богатый набор событий (dragStart, dragEnd, layoutEnd, add, remove). Для вложенных сеток важно учитывать:

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

Пример синхронизации:

nestedGrid.on('layoutEnd', () => {
  parentGrid.refreshItems().layout();
});

Таким образом, после перестановки элементов внутри вложенной сетки родительская сетка обновляет свои размеры и позиции элементов.

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

Muuri поддерживает возможность перетаскивания элементов между сетками, включая вложенные. Для этого используется настройка dragContainer и событие send. Пример:

const allGrids = [parentGrid, ...nestedGrids];

allGrids.forEach(grid => {
  grid.on('dragReleaseEnd', function(item) {
    const targetGrid = allGrids.find(g => g.getElement().contains(item.getElement()));
    if (targetGrid && targetGrid !== grid) {
      grid.remove(item, { removeElements: false });
      targetGrid.add(item);
    }
  });
});

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

Особенности производительности

При работе с вложенными сетками важно учитывать следующие моменты:

  • Каждая сетка требует отдельного расчета положения элементов. Чем глубже вложенность, тем выше нагрузка на рендеринг и анимацию.
  • Для сложных интерфейсов рекомендуется отключать анимацию или использовать throttling обновлений через requestAnimationFrame.
  • Вложенные сетки увеличивают сложность DOM-структуры, поэтому следует внимательно следить за размерами элементов и правильным использованием refreshItems() для предотвращения рассинхронизации.

Настройка стилей для вложенных сеток

CSS для вложенных сеток требует точного контроля размеров и внутренних отступов:

.grid, .nested-grid {
  display: flex;
  flex-wrap: wrap;
  margin: -8px;
}

.item, .nested-item {
  margin: 8px;
  background: #f0f0f0;
  border-radius: 4px;
}

.item-content {
  padding: 8px;
  background: #ffffff;
  border: 1px solid #ddd;
}
  • Вложенная сетка должна иметь отступы, соответствующие родительской, чтобы анимации перемещений выглядели плавно.
  • Высота и ширина .item должны учитывать размеры вложенной сетки для корректного позиционирования.

Резюме ключевых моментов

  • Вложенная сетка создаётся как отдельный экземпляр Muuri внутри элемента родительской сетки.
  • Каждая сетка управляет своими элементами, а взаимодействие осуществляется через события и методы refreshItems() и layout().
  • Перетаскивание между сетками возможно, но требует явной обработки событий.
  • Производительность напрямую зависит от количества сеток и глубины вложенности, поэтому оптимизация анимаций и обновлений критична.
  • Правильная стилизация и контроль размеров элементов обеспечивают корректное отображение и плавные анимации.

Вложенные сетки в Muuri позволяют создавать комплексные, интерактивные интерфейсы с независимой динамикой и гибким управлением элементами, что делает библиотеку особенно полезной для сложных веб-приложений.