Бесконечный скролл в Angular 9 с помощью Intersection Observer API

Aleksandr Serenko
F.A.F.N.U.R
Published in
3 min readFeb 21, 2020

В данной статье поговорим о том, как создать бесконечную прокрутку (infinite scroll) с помощью стандартных и современных веб технологий таких Intersection Observer API.

Одной из классических задач в современном UI это создание бесконечных скроллов контента, например, ленты в социальных сетях или новостные ленты наподобие яндекс дзена.

И если раньше требовались сложные решения, то в мире современного веба, есть решения, которые поддерживаются браузерами, в частности — Intersection Observer API.

Intersection Observer API позволяет разработчику отслеживать положение прокрутки относительно элементов и при необходимости выполнять пользовательскую логику.

Давайте создадим компонент.

Установка полифилов

Прежде чем начнём разрабатывать компонент, установим полифилы для корректной работы в IE и Edge:

yarn add intersection-observer

Подключим в файле всех полифилов в проекте src/polyfills.ts:

/***************************************************************************************************
* BROWSER POLYFILLS
*/
.../** IntersectionObserver polyfill for IE and Edge */
import 'intersection-observer';

Реализация компонента

Реализовывать компонент будем способом, предложенный Netanel Basal в статье Build an Infinite Scroll Component in Angular.

Принцип работы компонента:

Есть основная часть контента и блок, который располагается в самом низу основного контента.

Как только, хотя бы на один пиксель нижний блок появляется в области видимости блока, вызывается событие “scrolled”, которое говорит о том что пользователь дошел до конца станицы (компонента), и нужно загрузить новую часть контента.

Обычно интересны 2 случая:

  • Обычный бесконечный скролл, где мы следим условно за всем контентом
  • Бесконечный скролл реализован внутри конкретного HTML элемента, и нужно отслеживать прокрутку не всей страницы, а конкретного блока.

Создадим новый компонент:

ng g component infinite-scroll

Добавим реализацию:

Как уже упоминалось, есть основной контент, который представлен ng-content и якорь, отвечающий за низ(конец) контента.

<ng-content></ng-content>
<div #anchor></div>

Очень важно сделать компонент блоком, для правильного определения:

:host {
display: block;
}

Реализация самого компонента достаточно проста.

InfiniteScrollComponent принимает один входящий необязательный параметр — options.

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

После того как контент инициализирован (AfterViewInit), появляется доступ к якорю и возможности создать и связать IntersectionObserver.

this.observer = new IntersectionObserver(([entry]) => entry.isIntersecting && this.scrolled.emit(), {
root: this.isHostScrollable() ? this.host.nativeElement : null,
...this.options
});
this.observer.observe(this.anchor.nativeElement);
}

Как видно из кода, создаётся обычный IntersectionObserver, в который передаётся параметр root, который отвечает за отслеживаемый скролл в компоненте. По умолчанию это null, т.е. основной скролл веб страницы.

Метод isHostScrollable, проверяет есть ли на inititeScroll компоненте ограничение высоты, и если есть, то тогда для него устанавливается root на самого себя.

Демонстрация

Так как статья является частью цикла статей для Angular, то добавим в проект демо работы infinite-scroll.

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

Для примера с ограниченной высотой, будем просто дублировать текст

В app.component добавим немного логики:

Запустим проект и посмотрим:

yarn run infinite-scroll:serve

Откроем браузер http://localhost:4200:

Резюме

В ходе статьи добавили полифилы для корректной работы во всех браузерах, а также создали компонент для бесконечного скролла с помощью Intersection Observer API. Добавили демо для работы infinite-scroll.

Исходники

Все исходники находятся на github, в репозитории:

Для того, чтобы посмотреть состояние проекта на момент написания статьи, нужно выбрать соответствующий тег — infinite-scroll.

git checkout infinite-scroll

Код можно посмотреть в разделе https://github.com/Fafnur/medium-stories/tree/master/libs/shared/src/lib/components/infinite-scroll

Спасибо за внимание!
Подписывайтесь на канал, чтобы не пропустить новые статьи про Angular и новости из мира фронтенд разработки.

Добавляйтесь в группу ВК: https://vk.com/fafnur
Добавляйтесь в группу в Fb: https://www.facebook.com/groups/fafnur/
Телеграм канал: https://t.me/f_a_f_n_u_r
Twitter: https://twitter.com/Fafnur1

Предыдущие статьи:

  1. Динамические формы в Angular или автоматизируем создание Angular форм
  2. Создание переменных в шаблонах Angular. Превращение реактивных свойств в простые объекты.
  3. Angular 9, Universal и Nx. Новые правила сборки SSR приложения.
  4. Кроссплатформенные web storage в Angular 9. Реализация LocalStorage, SessionStorage и Cookies в Angular Universal.
  5. Мультиязычность ngx-translate в Angular 9 c монорепозиторием Nx.
  6. Разбиение локализации ngx-translate на несколько файлов в Nx

--

--

Aleksandr Serenko
F.A.F.N.U.R

Senior Front-end Developer, Angular evangelist, Nx apologist, NodeJS warlock