Множественные критерии сортировки

Для работы с Masonry необходимо подключить библиотеку через npm или CDN. После подключения создается экземпляр Masonry, который управляет сеткой элементов. Основная инициализация выглядит следующим образом:

import Masonry from 'masonry-layout';

const grid = document.querySelector('.grid');
const masonry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer',
  percentPosition: true,
  gutter: 10
});

Ключевые параметры:

  • itemSelector — селектор элементов сетки.
  • columnWidth — ширина колонки, может быть фиксированным числом или элементом-ссылкой (.grid-sizer).
  • percentPosition — позволяет использовать проценты для ширины колонок.
  • gutter — отступ между элементами сетки.

Инициализация Masonry создает динамическую сетку, которая подстраивается под размеры контейнера и элементов.


Сортировка элементов

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

const items = Array.from(grid.querySelectorAll('.grid-item'));

items.sort((a, b) => {
  const ratingA = parseInt(a.dataset.rating, 10);
  const ratingB = parseInt(b.dataset.rating, 10);
  const dateA = new Date(a.dataset.date);
  const dateB = new Date(b.dataset.date);

  // Сортировка по рейтингу, а затем по дате
  if (ratingA !== ratingB) {
    return ratingB - ratingA;
  }
  return dateB - dateA;
});

После сортировки DOM-элементы необходимо заново вставить в контейнер и обновить Masonry:

items.forEach(item => grid.appendChild(item));
masonry.reloadItems();
masonry.layout();

Множественные критерии сортировки

Для сложной сортировки применяется цепочка сравнений внутри функции sort. Основные подходы:

  1. Иерархическая сортировка Сначала определяется главный критерий, затем второстепенные. Пример: рейтинг → дата → алфавит.
items.sort((a, b) => {
  const ratingDiff = parseInt(b.dataset.rating) - parseInt(a.dataset.rating);
  if (ratingDiff !== 0) return ratingDiff;

  const dateDiff = new Date(b.dataset.date) - new Date(a.dataset.date);
  if (dateDiff !== 0) return dateDiff;

  const titleA = a.dataset.title.toLowerCase();
  const titleB = b.dataset.title.toLowerCase();
  return titleA.localeCompare(titleB);
});
  1. Сортировка с весовыми коэффициентами Каждому критерию присваивается коэффициент влияния. Итоговое значение используется для сравнения.
items.sort((a, b) => {
  const ratingWeight = 0.7;
  const dateWeight = 0.3;

  const ratingScore = parseInt(a.dataset.rating) * ratingWeight;
  const dateScore = new Date(a.dataset.date).getTime() * dateWeight;

  const totalA = ratingScore + dateScore;
  const totalB = parseInt(b.dataset.rating) * ratingWeight + new Date(b.dataset.date).getTime() * dateWeight;

  return totalB - totalA;
});
  1. Динамическая сортировка по выбранным критериям Критерии можно хранить в массиве объектов, содержащих имя атрибута и направление сортировки. Это удобно для интерфейсов с фильтрами и сортировкой по выбору пользователя.
const criteria = [
  { key: 'rating', order: 'desc' },
  { key: 'date', order: 'asc' },
];

items.sort((a, b) => {
  for (const criterion of criteria) {
    const valueA = a.dataset[criterion.key];
    const valueB = b.dataset[criterion.key];
    
    if (valueA !== valueB) {
      if (criterion.order === 'asc') return valueA > valueB ? 1 : -1;
      return valueA < valueB ? 1 : -1;
    }
  }
  return 0;
});

Оптимизация производительности

При большом количестве элементов важно минимизировать количество пересчетов макета Masonry. Эффективные подходы:

  • Групповая вставка элементов: сначала сортировка и вставка всех элементов в DOM, затем один вызов masonry.reloadItems() и masonry.layout().
  • Использование DocumentFragment: временный контейнер для вставки элементов вне DOM, что уменьшает количество перерисовок.
const fragment = document.createDocumentFragment();
items.forEach(item => fragment.appendChild(item));
grid.appendChild(fragment);
masonry.reloadItems();
masonry.layout();
  • Ленивая сортировка и фильтрация: обновлять макет только для видимых элементов, а скрытые держать отдельно.

Динамическое добавление и сортировка новых элементов

Новые элементы можно добавлять в Masonry с сохранением сортировки:

const newItem = document.createElement('div');
newItem.classList.add('grid-item');
newItem.dataset.rating = 5;
newItem.dataset.date = '2026-03-13';
grid.appendChild(newItem);

items.push(newItem);
items.sort((a, b) => parseInt(b.dataset.rating) - parseInt(a.dataset.rating));
items.forEach(item => grid.appendChild(item));

masonry.reloadItems();
masonry.layout();

Таким образом, Masonry позволяет комбинировать визуальный порядок с динамическими критериями сортировки, обеспечивая гибкую и отзывчивую сетку.


Дополнительные возможности Masonry для сортировки

  • Анимация при перестановке элементов: можно использовать CSS-переходы для плавного перемещения элементов после сортировки.
  • Интеграция с фильтрацией: вместе с display: none и сортировкой можно реализовать сложные интерфейсы с фильтрами по категориям и тегам.
  • События Masonry: события layoutComplete и removeComplete позволяют выполнять дополнительные действия после перестройки сетки.

Эти возможности делают Masonry мощным инструментом для создания адаптивных сеток с множественными критериями сортировки и динамическим обновлением контента.