Пагинация и infinite scroll

Библиотека Muuri предоставляет гибкий и мощный инструмент для создания сеток с возможностью динамического управления элементами. Для крупных коллекций контента важными аспектами являются пагинация и бесконечная прокрутка (infinite scroll). Эти подходы позволяют оптимизировать загрузку данных, уменьшить нагрузку на DOM и улучшить пользовательский опыт.


Пагинация

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

Инициализация сетки с пагинацией

const grid = new Muuri('.grid', {
  layout: {
    rounding: false
  }
});

const pageSize = 20;
let currentPage = 1;

Ключевые моменты:

  • pageSize определяет количество элементов на одной странице.
  • currentPage отслеживает текущую страницу для управления навигацией.
  • Настройка layout.rounding: false предотвращает некорректное позиционирование элементов при динамическом добавлении.

Отображение элементов текущей страницы

function showPage(page) {
  const start = (page - 1) * pageSize;
  const end = page * pageSize;
  
  grid.getItems().forEach((item, index) => {
    if (index >= start && index < end) {
      item.show();
    } else {
      item.hide();
    }
  });

  grid.layout();
}
  • item.show() и item.hide() управляют видимостью элементов.
  • Вызов grid.layout() пересчитывает позиции видимых элементов.

Управление навигацией между страницами

document.querySelector('#nextPage').addEventListener('click', () => {
  currentPage++;
  showPage(currentPage);
});

document.querySelector('#prevPage').addEventListener('click', () => {
  if (currentPage > 1) {
    currentPage--;
    showPage(currentPage);
  }
});
  • Можно добавлять проверку на максимальное количество страниц.
  • Пагинация легко комбинируется с фильтрацией и сортировкой Muuri.

Бесконечная прокрутка (Infinite Scroll)

Infinite Scroll динамически подгружает новые элементы при достижении конца контейнера. Muuri не имеет встроенного механизма загрузки данных, но полностью поддерживает динамическое добавление элементов с помощью grid.add().

Настройка события прокрутки

const container = document.querySelector('.grid-container');

container.addEventListener('scroll', () => {
  if (container.scrollTop + container.clientHeight >= container.scrollHeight - 10) {
    loadMoreItems();
  }
});
  • Проверка условия гарантирует подгрузку данных до достижения конца контейнера.
  • scrollHeight - 10 используется для компенсации мелких погрешностей браузера.

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

function loadMoreItems() {
  fetch('/api/items?offset=' + grid.getItems().length)
    .then(res => res.json())
    .then(data => {
      const elements = data.map(itemData => {
        const element = document.createElement('div');
        element.className = 'item';
        element.innerHTML = `<div class="item-content">${itemData.name}</div>`;
        return element;
      });
      grid.add(elements);
    });
}
  • grid.add(elements) автоматически интегрирует новые элементы в сетку.
  • Элементы сразу участвуют в анимации и раскладываются в соответствии с текущим layout.

Интеграция пагинации и Infinite Scroll

В больших проектах часто применяется комбинация подходов:

  • Начальная загрузка — первая «страница» элементов.
  • Прокрутка инициирует подгрузку следующих страниц.
  • Видимые элементы можно скрывать или удалять, чтобы избежать перегрузки DOM.
function loadPageOrScroll(page) {
  fetch('/api/items?page=' + page)
    .then(res => res.json())
    .then(data => {
      const elements = data.map(itemData => createGridItem(itemData));
      grid.add(elements);
    });
}

Особенности реализации:

  • createGridItem(itemData) возвращает элемент сетки с необходимыми классами и содержимым.
  • Можно комбинировать с фильтрацией и сортировкой Muuri.
  • Для оптимизации памяти старые элементы можно удалять: grid.remove(itemsToRemove, { removeElements: true }).

Советы по производительности

  1. Минимизировать количество элементов в DOM — хранить в сетке только видимые и ближайшие к просмотру элементы.
  2. Использовать виртуализацию — для огромных коллекций стоит интегрировать Muuri с виртуальными списками.
  3. Оптимизировать анимации — при динамическом добавлении элементов выставлять layout.rounding: false и включать layout: { duration: 300 }.
  4. Пакетная подгрузка — добавлять элементы порциями (например, по 20–50) для плавной анимации и меньшей нагрузки на браузер.

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