Загрузка данных с сервера

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


Подключение Masonry и подготовка контейнера

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

<div id="grid" class="grid">
  <div class="grid-item">Элемент 1</div>
  <div class="grid-item">Элемент 2</div>
</div>

<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>

Инициализация Masonry выполняется через:

const grid = document.querySelector('#grid');

const msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: '.grid-sizer', // можно задать элемент для расчета ширины колонки
  percentPosition: true,
  gutter: 10
});

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

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

Загрузка данных с сервера через Fetch API

Для динамической подгрузки контента используется Fetch API. Пример запроса JSON данных с сервера:

fetch('/api/items')
  .then(response => response.json())
  .then(data => {
    const itemsHTML = data.map(item => {
      const div = document.createElement('div');
      div.className = 'grid-item';
      div.innerHTML = `<img src="${item.image}" alt="${item.title}"><p>${item.title}</p>`;
      return div;
    });
    appendItemsToGrid(itemsHTML);
  })
  .catch(error => console.error('Ошибка при загрузке данных:', error));

Интеграция новых элементов в Masonry

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

function appendItemsToGrid(items) {
  items.forEach(item => grid.appendChild(item));

  // Сообщаем Masonry о добавленных элементах
  msnry.appended(items);

  // Пересчитываем расположение
  msnry.layout();
}

Пояснения:

  • msnry.appended(items) — сообщает Masonry о новых DOM-элементах, чтобы они были включены в расчёт сетки.
  • msnry.layout() — пересчитывает позиции всех элементов для правильного выравнивания.

Обработка изображений с динамической загрузкой

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

<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
imagesLoaded(grid, () => {
  msnry.layout();
});

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


Бесконечная прокрутка и загрузка по требованию

Для реализации подгрузки данных при прокрутке страницы используется событие scroll:

window.addEventListener('scroll', () => {
  if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {
    loadMoreItems();
  }
});

let page = 1;
function loadMoreItems() {
  page++;
  fetch(`/api/items?page=${page}`)
    .then(response => response.json())
    .then(data => {
      const itemsHTML = data.map(item => {
        const div = document.createElement('div');
        div.className = 'grid-item';
        div.innerHTML = `<img src="${item.image}" alt="${item.title}"><p>${item.title}</p>`;
        return div;
      });
      appendItemsToGrid(itemsHTML);

      imagesLoaded(grid, () => {
        msnry.layout();
      });
    });
}

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

  • Подгрузка происходит перед достижением конца страницы (-500 пикселей).
  • Номер страницы передаётся на сервер для пагинации.
  • Использование imagesLoaded после вставки новых элементов предотвращает смещение сетки.

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

  1. Фрагменты DOM: создание элементов через DocumentFragment уменьшает количество перерисовок:
const fragment = document.createDocumentFragment();
items.forEach(item => fragment.appendChild(item));
grid.appendChild(fragment);
msnry.appended(items);
msnry.layout();
  1. Ленивая загрузка изображений с loading="lazy" сокращает количество одновременно загружаемых данных:
<img src="image.jpg" alt="title" loading="lazy">
  1. Дебаунс событий скролла для предотвращения слишком частых вызовов:
let debounceTimer;
window.addEventListener('scroll', () => {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(checkScroll, 200);
});

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

Для удаления элементов из Masonry используется метод remove:

const itemToRemove = document.querySelector('.grid-item-to-remove');
msnry.remove(itemToRemove);
msnry.layout();

Для обновления содержимого элемента достаточно изменить DOM внутри элемента и вызвать msnry.layout().


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