Бесконечный скролл в Angular 9 с помощью Intersection Observer API
В данной статье поговорим о том, как создать бесконечную прокрутку (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
Предыдущие статьи:
- Динамические формы в Angular или автоматизируем создание Angular форм
- Создание переменных в шаблонах Angular. Превращение реактивных свойств в простые объекты.
- Angular 9, Universal и Nx. Новые правила сборки SSR приложения.
- Кроссплатформенные web storage в Angular 9. Реализация LocalStorage, SessionStorage и Cookies в Angular Universal.
- Мультиязычность ngx-translate в Angular 9 c монорепозиторием Nx.
- Разбиение локализации ngx-translate на несколько файлов в Nx