Библиотека Muuri предоставляет мощные инструменты для построения динамических сеток с возможностью перетаскивания элементов и анимаций. Одной из ключевых особенностей является способность корректно реагировать на изменения в DOM, будь то добавление, удаление или изменение размеров элементов. Правильное управление обновлением сетки после таких изменений обеспечивает стабильность и плавность интерфейса.
Muuri использует несколько методов для синхронизации состояния сетки с реальным DOM:
refreshItems() Метод обновляет
внутреннее представление элементов сетки. Его стоит вызывать после того,
как элементы были добавлены, удалены или их размеры изменились. Пример
использования:
const grid = new Muuri('.grid');
// Добавление нового элемента в DOM
const newItem = document.createElement('div');
newItem.classList.add('item');
grid.getElement().appendChild(newItem);
// Обновление сетки
grid.refreshItems().layout();
Здесь refreshItems() сканирует DOM и
добавляет новые элементы в внутреннюю структуру Muuri, а
layout() пересчитывает расположение всех
элементов.
add() и remove() Эти
методы позволяют более явно управлять элементами сетки:
const newItem = document.createElement('div');
newItem.classList.add('item');
grid.add(newItem); // автоматически обновляет внутреннюю структуру и выполняет анимацию
Удаление элемента:
const itemToRemove = grid.getItems()[0];
grid.remove(itemToRemove, { removeElements: true });
Параметр removeElements: true
гарантирует удаление элемента из DOM одновременно с его удалением из
сетки.
layout() Метод отвечает
исключительно за перераспределение элементов. Вызывать его следует после
любых изменений, влияющих на размеры или порядок элементов.
grid.layout(true); // true означает принудительное перераспределение всех элементовMuuri может автоматически отслеживать изменения размеров элементов с
помощью dragRelease и resize
событий. Однако в случаях динамического изменения контента (например,
загрузка изображений или изменение текста) рекомендуется использовать
refreshItems() с последующим
layout().
Пример с изображениями:
const images = grid.getItems().map(item => item.getElement().querySelector('img'));
images.forEach(img => {
img.onl oad = () => {
grid.refreshItems([img.parentElement]).layout();
};
});
Здесь refreshItems([element]) обновляет только
конкретный элемент, что экономит ресурсы при больших сетках.
Muuri предоставляет возможность управлять сеткой при частых изменениях DOM без полной пересборки:
const items = [];
for (let i = 0; i < 10; i++) {
const el = document.createElement('div');
el.classList.add('item');
el.textContent = `Элемент ${i}`;
items.push(el);
}
grid.add(items);
const itemsToRemove = grid.getItems().filter(item => item.getElement().textContent.includes('Удалить'));
grid.remove(itemsToRemove, { removeElements: true });
Использование массивов ускоряет процесс и минимизирует количество анимаций при массовых изменениях.
Для сложных интерфейсов, где DOM изменяется динамически, эффективным
решением является MutationObserver:
const observer = new MutationObserver(mutations => {
let needsRefresh = false;
mutations.forEach(mutation => {
if (mutation.addedNodes.length || mutation.removedNodes.length) {
needsRefresh = true;
}
});
if (needsRefresh) {
grid.refreshItems().layout();
}
});
observer.observe(grid.getElement(), { childList: true, subtree: true });
MutationObserver отслеживает добавление и удаление
элементов, автоматически вызывая обновление сетки только при
необходимости. Это позволяет поддерживать высокую производительность при
большом количестве динамических изменений.
refreshItems([element1, element2]) вместо
refreshItems() для всей сетки.layout(): Не
вызывать layout() после каждого отдельного изменения, а
комбинировать с refreshItems().При работе с контентом, загружаемым асинхронно (например, с API), важно обновлять сетку после полной загрузки элементов:
fetch('/api/items')
.then(res => res.json())
.then(data => {
const elements = data.map(item => {
const el = document.createElement('div');
el.classList.add('item');
el.textContent = item.name;
return el;
});
grid.add(elements);
});
Здесь grid.add(elements) автоматически интегрирует новые
элементы в сетку и запускает анимацию их появления.
refreshItems() после
любых изменений DOM, влияющих на элементы сетки.layout() обязателен для
перерасчета положения элементов.Эти методы обеспечивают стабильную работу сетки Muuri в любых сценариях динамического контента, поддерживая плавность анимаций и корректное расположение элементов.