В контексте работы с библиотекой Masonry детекция достижения конца списка является критическим элементом для реализации бесконечной прокрутки, динамической подгрузки контента и оптимизации пользовательского интерфейса. Masonry управляет расположением элементов сетки по принципу «плиток», где каждый элемент выстраивается в колонках так, чтобы минимизировать вертикальные промежутки. Контроль момента достижения конца списка позволяет инициировать подгрузку новых элементов до того, как пользователь достигнет низа страницы.
Основная идея заключается в определении нижней границы контейнера Masonry относительно окна просмотра (viewport). Для этого используются методы JavaScript, позволяющие определить положение элемента на странице:
const grid = document.querySelector('.grid');
const lastItem = grid.lastElementChild;
const lastItemOffset = lastItem.offsetTop + lastItem.offsetHeight;
const pageOffset = window.pageYOffset + window.innerHeight;
Здесь:
lastItem.offsetTop — расстояние от верхнего края
документа до верхнего края последнего элемента сетки.lastItem.offsetHeight — высота последнего
элемента.window.pageYOffset — текущая вертикальная прокрутка
страницы.window.innerHeight — высота видимой области окна
браузера.Сравнение lastItemOffset и
pageOffset позволяет определить, достиг ли
пользователь конца списка:
if (pageOffset >= lastItemOffset) {
// Достигнут конец списка
loadMoreItems();
}
Детекция конца списка обычно выполняется при событии
scroll. Для оптимизации производительности используется
throttle или debounce, чтобы не
вызывать проверку слишком часто:
let isThrottled = false;
window.addEventListener('scroll', () => {
if (isThrottled) return;
isThrottled = true;
setTimeout(() => {
checkEndOfList();
isThrottled = false;
}, 200);
});
function checkEndOfList() {
const lastItem = document.querySelector('.grid').lastElementChild;
const lastItemOffset = lastItem.offsetTop + lastItem.offsetHeight;
const pageOffset = window.pageYOffset + window.innerHeight;
if (pageOffset >= lastItemOffset) {
loadMoreItems();
}
}
Принцип работы throttle: ограничение частоты вызова функции, предотвращающее перегрузку при активной прокрутке.
После добавления новых элементов необходимо обновить Masonry, чтобы правильно рассчитать расположение плиток:
const msnry = new Masonry('.grid', {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
function loadMoreItems() {
fetch('/api/items')
.then(response => response.json())
.then(data => {
const fragment = document.createDocumentFragment();
data.forEach(itemData => {
const item = document.createElement('div');
item.className = 'grid-item';
item.innerHTML = itemData.content;
fragment.appendChild(item);
});
const grid = document.querySelector('.grid');
grid.appendChild(fragment);
msnry.appended(fragment.children);
});
}
Метод msnry.appended() сообщает Masonry о новых
элементах и позволяет библиотеке корректно перестроить сетку без полной
перерисовки.
Для более плавного UX часто используют срабатывание загрузки до достижения конца списка, например, за 200–300 пикселей до низа. Это вычисляется путем добавления «буфера»:
const buffer = 300; // пиксели до конца
if (pageOffset + buffer >= lastItemOffset) {
loadMoreItems();
}
Такой подход предотвращает паузы при скролле и делает интерфейс более отзывчивым.
При изменении размеров окна или ориентации устройства важно пересчитывать положение последнего элемента, так как сетка Masonry адаптивная:
window.addEventListener('resize', () => {
checkEndOfList();
});
Masonry использует свой механизм layout() для
перерасчета сетки, который можно вызывать после динамической подгрузки
или изменения размеров:
msnry.layout();
pageOffset и
lastItemOffset обеспечивает простую проверку достижения
конца списка.scroll.appended() и layout()
поддерживают корректное отображение новых элементов.Эти методы вместе образуют надежную систему детекции конца списка, позволяя создавать динамические и отзывчивые интерфейсы с Masonry.