Для работы с 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. Основные подходы:
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);
});
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;
});
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. Эффективные подходы:
masonry.reloadItems() и masonry.layout().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 позволяет комбинировать визуальный порядок с динамическими критериями сортировки, обеспечивая гибкую и отзывчивую сетку.
display: none и сортировкой можно реализовать сложные
интерфейсы с фильтрами по категориям и тегам.layoutComplete и removeComplete позволяют
выполнять дополнительные действия после перестройки сетки.Эти возможности делают Masonry мощным инструментом для создания адаптивных сеток с множественными критериями сортировки и динамическим обновлением контента.