Gridstack.js управляет размещением и визуальным обновлением элементов сетки через систему внутренних вычислений координат и последующей синхронизации с DOM. Перерисовка происходит каждый раз, когда изменяется положение, размер или состояние одного или нескольких виджетов.
Основная цель механизма — минимизировать количество операций с DOM и обеспечить плавность интерфейса при сложных перестановках элементов.
Внутренний алгоритм перерисовки опирается на несколько ключевых этапов:
Каждый этап выполняется только при необходимости, что позволяет избегать лишних операций.
Gridstack.js использует внутреннюю структуру данных, представляющую сетку и размещённые в ней элементы. Эта модель содержит информацию:
Внутренний объект узла обычно имеет структуру:
{
x: 0,
y: 0,
w: 2,
h: 2,
id: "widget-1",
locked: false,
noResize: false,
noMove: false
}
Любое изменение сначала происходит в этой модели, и только затем отражается в DOM. Благодаря этому перерисовка может быть отложена или объединена.
Перерисовка сетки запускается при следующих действиях:
Изменение позиции элемента
Изменение размера
Добавление или удаление виджетов
addWidget()removeWidget()Изменение структуры сетки
Восстановление состояния
Каждый из этих процессов может инициировать каскадное обновление других элементов.
При изменении положения одного элемента Gridstack выполняет последовательность действий:
Псевдологика процесса:
update node
check collisions
resolve layout
update engine state
apply to DOM
emit events
Важная особенность — DOM не обновляется после каждого промежуточного шага.
Для повышения производительности Gridstack поддерживает режим групповых изменений.
Методы:
grid.batchUpdate(true)
grid.batchUpdate(false)
Когда batch режим включён:
После выключения режима выполняется единая перерисовка.
Пример:
grid.batchUpdate();
grid.addWidget({x:0, y:0, w:2, h:2});
grid.addWidget({x:2, y:0, w:2, h:2});
grid.addWidget({x:4, y:0, w:2, h:2});
grid.batchUpdate(false);
В этом случае происходит только одна перерисовка, а не три.
engine._notify()После завершения вычислений Gridstack уведомляет систему событий.
Это используется для:
Типичные события:
changeaddedremoveddragstopresizestopПример подписки:
grid.on('change', function(event, items) {
console.log(items);
});
Событие change содержит список элементов, которые были
изменены.
Gridstack поддерживает адаптацию сетки к изменению размеров родительского элемента.
Используется механизм наблюдения за размерами (ResizeObserver). Когда ширина контейнера меняется:
Пример реакции на изменение колонок:
grid.column(6);
После вызова происходит перераспределение элементов.
Gridstack применяет позиционирование элементов через CSS-свойства.
Основные свойства:
left
top
width
height
В некоторых конфигурациях используется CSS-трансформация:
transform: translate(...)
Такой подход позволяет:
Пример DOM-элемента:
<div class="grid-stack-item"
gs-x="1"
gs-y="2"
gs-w="3"
gs-h="2">
</div>
Атрибуты gs-* используются как декларативное описание
положения.
Gridstack реализует несколько оптимизаций.
Минимизация изменений DOM
Обновляются только элементы, координаты которых изменились.
Отложенная перерисовка
Batch-режим позволяет объединять операции.
Детекция коллизий
Алгоритм перемещает только необходимые элементы.
Кэширование размеров
Размеры колонок и строки вычисляются один раз.
Иногда требуется обновить интерфейс вручную. Для этого используется метод:
grid._updateContainerHeight();
Или более безопасный вариант:
grid.commit();
Этот метод завершает batch-операции и применяет изменения.
update()Метод update() позволяет изменить свойства элемента и
инициировать перерасчёт.
Пример:
grid.update(el, {
x: 3,
y: 1,
w: 4,
h: 2
});
Происходит:
Gridstack поддерживает плавные анимации перемещения.
Активируется через CSS:
.grid-stack-item {
transition: all 0.2s ease;
}
Когда координаты меняются, браузер анимирует изменение.
Анимация применяется к:
Во время drag-операций сетка постоянно обновляет позицию временного элемента.
Алгоритм:
После отпускания мыши выполняется окончательная фиксация.
Во время перетаскивания Gridstack использует placeholder-элемент.
Он:
Пример DOM:
<div class="grid-stack-placeholder"></div>
Этот элемент участвует в визуальной перерисовке, но удаляется после завершения операции.
Состояние сетки может восстанавливаться из JSON.
Пример:
grid.load(layout);
Алгоритм:
Изменение количества колонок вызывает глобальный пересчёт.
Метод:
grid.column(12);
Gridstack:
При уменьшении колонок возможны перестановки элементов.
После каждой перерисовки Gridstack поддерживает согласованность между:
DOM-атрибуты gs-x, gs-y, gs-w,
gs-h всегда обновляются.
Это позволяет:
Основные методы:
batchUpdate
grid.batchUpdate(true);
commit
grid.commit();
update
grid.update(el, options);
load
grid.load(layout);
column
grid.column(n);
Комбинация этих методов позволяет полностью контролировать процесс перерисовки сетки.
Группировать изменения
Всегда использовать batch-режим при массовых операциях.
Избегать лишних update
Каждый вызов update() может инициировать перерасчёт.
Ограничивать количество элементов
Большие сетки (100+ элементов) требуют аккуратного управления обновлениями.
Минимизировать CSS-эффекты
Сложные тени и фильтры могут замедлять анимацию.
При анализе поведения сетки полезно отслеживать события:
grid.on('change added removed', function(e, items) {
console.log(items);
});
Также можно временно отключить анимации:
.grid-stack-item {
transition: none;
}
Это помогает увидеть реальные изменения координат без задержек.
При использовании с React, Vue или Angular важно учитывать:
Поэтому рекомендуется:
Основная логика перерасчёта сетки находится в классе
GridStackEngine.
Он отвечает за:
GridStackEngine не взаимодействует напрямую с DOM.
Это разделение позволяет: