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

Библиотека Masonry предназначена для создания динамических сеток с кирпичной раскладкой, позволяя автоматически распределять элементы по высоте и ширине контейнера. Помимо базового позиционирования, одной из ключевых возможностей является сортировка элементов по атрибутам, что позволяет организовывать содержимое сетки в зависимости от заданных критериев.


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

Для корректной работы сортировки необходимо, чтобы каждый элемент сетки содержал атрибуты или data-атрибуты, по которым будет выполняться сортировка. Обычно используют атрибуты data-*, например:

<div class="grid">
  <div class="grid-item" data-name="Alpha" data-price="30">...</div>
  <div class="grid-item" data-name="Beta" data-price="20">...</div>
  <div class="grid-item" data-name="Gamma" data-price="50">...</div>
</div>
  • data-name — строковый атрибут, по которому можно сортировать алфавитно.
  • data-price — числовой атрибут для сортировки по цене.

Важно, чтобы все элементы имели одинаковый набор атрибутов, иначе сортировка может работать некорректно.


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

Для работы с Masonry нужно подключить библиотеку и инициализировать сетку:

var grid = document.querySelector('.grid');
var msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: '.grid-item',
  percentPosition: true
});

Параметр itemSelector указывает на элементы, которые Masonry будет размещать, а columnWidth и percentPosition обеспечивают гибкое выравнивание элементов независимо от ширины контейнера.


Сортировка с использованием Array.prototype.sort

Masonry сам по себе не предоставляет встроенного метода сортировки по атрибутам, но сортировка достигается через изменение порядка элементов в DOM и последующий вызов layout():

function sortByAttribute(attr, isNumeric = false, ascending = true) {
  var items = Array.from(grid.children);

  items.sort(function(a, b) {
    var aValue = a.getAttribute(attr) || a.dataset[attr];
    var bValue = b.getAttribute(attr) || b.dataset[attr];

    if (isNumeric) {
      aValue = parseFloat(aValue);
      bValue = parseFloat(bValue);
    }

    if (aValue > bValue) return ascending ? 1 : -1;
    if (aValue < bValue) return ascending ? -1 : 1;
    return 0;
  });

  items.forEach(function(item) {
    grid.appendChild(item);
  });

  msnry.layout();
}
  • attr — название атрибута (data-name, data-price).
  • isNumeric — флаг, указывающий, что значения числовые.
  • ascending — направление сортировки: true для возрастания, false для убывания.

Этот метод позволяет динамически сортировать сетку без перезагрузки страницы.


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

Иногда требуется сортировка по нескольким критериям. Для этого используют кастомную функцию сравнения:

items.sort(function(a, b) {
  var priceA = parseFloat(a.dataset.price);
  var priceB = parseFloat(b.dataset.price);
  if (priceA !== priceB) return priceA - priceB;

  var nameA = a.dataset.name.toLowerCase();
  var nameB = b.dataset.name.toLowerCase();
  return nameA.localeCompare(nameB);
});

В этом примере сначала сортировка выполняется по цене, а при равных значениях — по имени в алфавитном порядке.


Сортировка с использованием библиотек-помощников

Для более сложной логики сортировки можно использовать библиотеку jQuery или сторонние утилиты вроде Lodash. Например, с Lodash _.sortBy:

var sorted = _.sortBy(Array.from(grid.children), [function(el) {
  return parseFloat(el.dataset.price);
}, function(el) {
  return el.dataset.name.toLowerCase();
}]);

sorted.forEach(function(item) {
  grid.appendChild(item);
});
msnry.layout();

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


Анимация при сортировке

Чтобы переход элементов был плавным, Masonry поддерживает CSS-переходы и анимацию. Для этого рекомендуется добавлять следующие стили:

.grid-item {
  transition: transform 0.4s ease;
}

При вызове msnry.layout() элементы перемещаются плавно, создавая эффект живой перестановки в сетке.


Динамическая сортировка на основе пользовательских действий

Для интерактивного изменения порядка элементов можно привязать сортировку к кнопкам или выпадающим спискам:

document.querySelector('#sort-price').addEventListener('click', function() {
  sortByAttribute('data-price', true, true);
});

document.querySelector('#sort-name').addEventListener('click', function() {
  sortByAttribute('data-name', false, true);
});

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


Оптимизация больших сеток

При работе с большим количеством элементов рекомендуется:

  1. Использовать document fragments для вставки отсортированных элементов, чтобы минимизировать количество операций с DOM.
  2. Включить percentPosition: true, чтобы Masonry правильно рассчитывал расположение при адаптивной ширине.
  3. Ограничить количество одновременных вызовов layout(), объединяя несколько операций сортировки в один вызов.

Эти меры обеспечивают быструю и плавную перестройку сетки при сортировке.