Сохранение порядка элементов

Библиотека Masonry.js предоставляет мощный механизм для динамической верстки элементов в виде сетки, где элементы упорядочиваются в колонки по высоте, образуя так называемый «кирпичный» макет. Важной задачей при работе с Masonry является сохранение порядка элементов, особенно когда элементы подгружаются динамически или используются фильтры и сортировка.


Основы размещения элементов

По умолчанию Masonry использует стратегию layout by height, где каждый элемент помещается в колонку с наименьшей суммарной высотой. Такая стратегия приводит к визуально плотной сетке, но может нарушать исходный порядок элементов в DOM. Для сохранения последовательности нужно учитывать следующие моменты:

  1. Сортировка элементов в DOM Masonry опирается на порядок элементов в DOM при первичной инициализации. Если элементы добавляются динамически, необходимо вставлять их в DOM в нужной последовательности перед вызовом метода appended:

    const grid = document.querySelector('.grid');
    const msnry = new Masonry(grid, {
        itemSelector: '.grid-item',
        columnWidth: '.grid-sizer',
        percentPosition: true
    });
    
    // Создание нового элемента
    const newItem = document.createElement('div');
    newItem.classList.add('grid-item');
    newItem.textContent = 'Новый элемент';
    
    // Вставка перед последним элементом, чтобы сохранить порядок
    grid.insertBefore(newItem, grid.children[2]);
    
    // Обновление Masonry
    msnry.appended(newItem);

    Здесь важно, что порядок в DOM определяет визуальное размещение, если используется метод appended.

  2. Использование originLeft и originTop Параметры originLeft и originTop влияют на то, откуда Masonry начинает раскладывать элементы. Для сохранения естественного порядка лучше оставить значения по умолчанию (true) или явным образом задавать, если требуется специфическая ориентация:

    const msnry = new Masonry(grid, {
        itemSelector: '.grid-item',
        columnWidth: '.grid-sizer',
        percentPosition: true,
        originLeft: true,
        originTop: true
    });

    Изменение этих параметров может визуально «перетасовать» элементы, что нарушит порядок.


Динамическая подгрузка элементов

При асинхронной загрузке контента, например через AJAX, порядок элементов часто теряется. Чтобы сохранить последовательность:

  1. Сортировать массив данных на стороне JavaScript до создания DOM-элементов.
  2. Создавать элементы в строго нужном порядке.
  3. Использовать метод append или appended после добавления в DOM.

Пример с асинхронной подгрузкой:

fetch('/api/items')
  .then(res => res.json())
  .then(items => {
      items.sort((a, b) => a.id - b.id); // Сортировка по id
      const fragment = document.createDocumentFragment();
      
      items.forEach(itemData => {
          const item = document.createElement('div');
          item.classList.add('grid-item');
          item.textContent = itemData.name;
          fragment.appendChild(item);
      });

      grid.appendChild(fragment);
      msnry.appended(Array.from(fragment.children));
  });

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


Фильтрация и сортировка

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

  • Скрытие элементов через CSS: display: none; или visibility: hidden;. Masonry автоматически пересчитает layout, но элементы, скрытые таким образом, остаются в исходном порядке DOM.
  • Пересоздание Masonry после фильтрации: иногда проще удалить все элементы из сетки и заново добавить их в нужной последовательности.

Пример фильтрации по классу:

const allItems = Array.from(grid.children);
allItems.forEach(item => {
    if (!item.classList.contains('active')) {
        item.style.display = 'none';
    } else {
        item.style.display = '';
    }
});
msnry.layout(); // Пересчет сетки без изменения порядка

Сохранение анимации при порядке элементов

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

  • Не менять порядок элементов в DOM во время анимации.
  • Использовать методы layout и appended, которые пересчитывают позиции без перестановки DOM-узлов.
  • Добавлять классы с CSS-переходами для плавного перемещения:
.grid-item {
    transition: transform 0.4s ease;
}

Jav * aScript:

msnry.layout(); // Masonry плавно перемещает элементы

Работа с фильтрами и сохранением порядка через массив

Для сложных случаев, когда элементы фильтруются и добавляются динамически, удобно хранить отдельный массив объектов, отражающих порядок:

let itemsArray = [];

function addItem(itemData) {
    const item = document.createElement('div');
    item.classList.add('grid-item');
    item.textContent = itemData.name;
    itemsArray.push(item);
    grid.appendChild(item);
    msnry.appended(item);
}

function filterItems(predicate) {
    grid.innerHTML = '';
    const filtered = itemsArray.filter(predicate);
    filtered.forEach(item => grid.appendChild(item));
    msnry.layout();
}

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


Выводы по сохранению порядка

  • Порядок элементов в DOM критичен для Masonry.
  • Использование appended и layout обеспечивает правильное перераспределение без изменения последовательности.
  • Для динамических сеток лучше хранить элементы в массиве или структуре данных, чтобы при фильтрации или сортировке порядок оставался предсказуемым.
  • CSS-анимации и параметры originLeft/originTop помогают поддерживать визуальную согласованность при перестройке сетки.

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