Автоподгрузка пагинации

Теория процесса:

  1. На странице должна быть рабочая обычная пагинация с уникальным селектором на кнопки "следующая страница".
  2. Блок пагинации скрываем (но не убираем).
  3. Вешаем скрипт, который отслеживает событие окна scroll, и, как только скроллинг страницы достиг низа (координаты самого блока пагинации или последней строки товаров), выполняем аякс по ссылке кнопки следующей страницы пагинации (из п.1).
  4. Из полученного в п.3 контена вытаскиваем товары и добавляем их в листинг текущей страницы. Из того же контента выдергиваем пагинацию и ЗАМЕНЯЕМ на нее пагинацию текущей страницы.
  5. Если надо - для загруженных товаров инициализируем события, которые должны на них висеть.
  6. Еще можно перед отправкой аякса устанавливать флаг процесса загрузки и отключать после получения данных - этим можно предотвратить отправку множества запросов при активном скроллинге.

Рабочий пример скрипта:

function initAutoPage(){
    let clist = document.querySelector('.catalog-list');
    let pages = document.querySelector('nav.pages');
    if(!clist || !pages) return false;
    
    window.addEventListener('scroll', e => {
        if(window.loadingPage) return false;
        
        if(pages.offsetTop < window.pageYOffset + screen.availHeight){
            pages.querySelectorAll('.page-next a.page-link').forEach(link => {
                window.loadingPage = true;

                let data = new FormData();
                data.append('tmpl', 'raw');
                fetch(link.href, {  
                    method: 'post',  
                    body: data
                }).then(function(resp) {  
                    if(resp.status == 200){
                        resp.text().then(function(resp){
                            let cont = document.createElement('div');
                            cont.innerHTML = resp;
                            cont.querySelectorAll('.catalog-item').forEach(citem => {
                                clist.appendChild(citem);
                            });
                            initCountItems();
                            pages.innerHTML = '';
                            cont.querySelectorAll('nav.pages').forEach(navpg => {
                                pages.innerHTML = navpg.innerHTML;
                            });
                        });
                        window.loadingPage = false;
                    }
                });
            });
        }
    }, false);

    window.dispatchEvent(new Event('scroll'));
}