Библиотека Muuri предоставляет мощный механизм для динамического управления сеткой элементов. Одной из ключевых возможностей является сортировка элементов по их атрибутам, что позволяет организовать контент в зависимости от данных, хранящихся в элементах.
Элементы, которые необходимо сортировать, должны содержать пользовательские атрибуты, например:
<div class="grid">
<div class="item" data-name="Яблоко" data-price="50"></div>
<div class="item" data-name="Банан" data-price="30"></div>
<div class="item" data-name="Виноград" data-price="70"></div>
</div>
Здесь используется два атрибута: data-name и
data-price. Эти атрибуты станут основой для сортировки по
различным критериям.
Сетка создаётся следующим образом:
const grid = new Muuri('.grid', {
dragEnabled: true,
layout: {
rounding: false
}
});
Опция dragEnabled позволяет перетаскивать элементы, а
layout.rounding контролирует округление координат при
перестроении сетки.
Метод sort() позволяет определить порядок элементов. Для
сортировки по атрибуту необходимо передать функцию:
grid.sort((itemA, itemB) => {
const priceA = parseInt(itemA.getElement().dataset.price, 10);
const priceB = parseInt(itemB.getElement().dataset.price, 10);
return priceA - priceB;
});
Пояснение:
itemA.getElement() — возвращает DOM-элемент элемента
сетки.dataset.price — получает значение атрибута
data-price.parseInt(..., 10) — преобразует строку в число.Для сортировки по строковым атрибутам, например
data-name, используется стандартное сравнение строк:
grid.sort((itemA, itemB) => {
const nameA = itemA.getElement().dataset.name.toLowerCase();
const nameB = itemB.getElement().dataset.name.toLowerCase();
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
return 0;
});
Использование toLowerCase() обеспечивает
регистронезависимую сортировку, что особенно важно при
работе с текстовыми данными.
Можно сортировать по нескольким атрибутам одновременно. Например, сначала по цене, а затем по имени:
grid.sort((itemA, itemB) => {
const priceA = parseInt(itemA.getElement().dataset.price, 10);
const priceB = parseInt(itemB.getElement().dataset.price, 10);
if (priceA !== priceB) {
return priceA - priceB;
}
const nameA = itemA.getElement().dataset.name.toLowerCase();
const nameB = itemB.getElement().dataset.name.toLowerCase();
if (nameA < nameB) return -1;
if (nameA > nameB) return 1;
return 0;
});
Такой подход позволяет создавать многоуровневые критерии сортировки, что особенно полезно для сложных интерфейсов.
После изменения атрибутов элементов можно заново отсортировать сетку:
itemElement.dataset.price = "45";
grid.refreshItems().sort((a, b) => parseInt(a.getElement().dataset.price, 10) - parseInt(b.getElement().dataset.price, 10));
Метод refreshItems() обновляет внутренние данные Muuri,
что гарантирует корректную сортировку после изменения атрибутов.
Muuri обеспечивает анимацию при перестановке элементов. Для тонкой
настройки можно использовать параметры layout:
grid.sort(...).layout({
duration: 400,
easing: 'ease-in-out'
});
duration — время анимации в миллисекундах.easing — функция плавности перехода
(linear, ease-in, ease-out,
ease-in-out).Для комбинирования сортировки и фильтрации можно использовать
filter() и sort() совместно:
grid.filter(item => parseInt(item.getElement().dataset.price, 10) > 40)
.sort((a, b) => parseInt(a.getElement().dataset.price, 10) - parseInt(b.getElement().dataset.price, 10));
Такой подход позволяет отображать только элементы, соответствующие условию, и одновременно сортировать их по нужному атрибуту.
Для сортировки в обратном порядке достаточно изменить направление сравнения:
grid.sort((itemA, itemB) => {
const priceA = parseInt(itemA.getElement().dataset.price, 10);
const priceB = parseInt(itemB.getElement().dataset.price, 10);
return priceB - priceA;
});
Это удобно для реализации функций «от дорогого к дешевому» или «от Z до A».
dataset вместо
getAttribute() ускоряет доступ к атрибутам.dragEnabled сортировка может быть
интегрирована с перетаскиванием для создания интерактивного опыта.