들어가며
노션 프로젝트를 핑계로 TIL을 작성하지 않았다. 꾸준함이 중요하다고 생각하기 때문에 간단하게라도 정리하는 습관을 들여야겠다.
무한 스크롤
무한 스크롤은 현재 다양한 앱에서 사용하고 있다. 대표적인 예로 유튜브가 있다. 유튜브 앱을 열면 처음에는 몇 개의 동영상이 로딩되어 있다. 유튜브 앱 우측을 보면 스크롤 바가 있는데 처음에는 스크롤 바의 크기가 매우 크지만 화면을 아래로 내리면 내릴수록 스크롤 바가 작아지는 것을 확인할 수 있다. 하단에 영상을 추가하기 때문에 컨텐츠 크기가 늘어가 스크롤 바가 작아지는 것이다.
무한 스크롤은 정보를 명확하게 찾지 않아도 되는 서비스에 사용할 수 있을 것 같다. 아무 생각 없이 상품을 구경하는 쇼핑몰이라거나, 스크롤을 내리며 재밌어 보이는 동영상을 찾는 유튜브등에서 간단한 스크롤 이벤트 만으로 새로운 정보를 불러오기 때문에 많이 사용하는 것 같다.
무한 스크롤을 구현하는 방식은 크게 두 가지가 있다. 하나는 전통적인 스크롤 이벤트를 이용하는 방식이고, 다른 하나는 Intersection Observer를 이용하는 방식이다.
스크롤 이벤트를 사용한 무한 스크롤 구현 스크롤 바가 있는 요소에서 스크롤을 하면 스크롤 이벤트가 발생한다. 스크롤 이벤트가 발생했을 때 스크롤 바의 위치가 페이지의 아래라면 새로운 데이터를 불러오는 작업을 수행한다.
1 window.addEventListener("scroll", (e) => {2 console.log(3 window.innerHeight + window.scrollY >= document.body.offsetHeight4 );5 });위의 함수는 스크롤 바가 화면 하단에 도착하면 true를 반환한다. 이렇게 되면 화면 끝에 도달해서 더이상 컨텐츠가 없을 때 데이터를 요청하기 때문에 사용자 경험에 좋지 않을 수 있다. 그렇기 때문에 약간의 보정을 주어 화면 끝에 도달했을 때는 데이터를 불러와 바로 사용자가 볼 수 있게 처리하는 것이 좋다. 스크롤 이벤트를 사용해 무한 스크롤을 구현하면 간단하게 구현할 수 있다는 장점이 있지만 스크롤 할 때마다 함수가 실행되기 때문에 성능 문제가 생길 수 있다. 이 때 쓰로틀링을 사용해 구현한다고 한다. > 쓰로틀링이란? > 함수가 연속적으로 계속 실행되는 상황에서 마지막 함수가 호출된 후 일정 시간이 지나기 전에 함수를 실행하지 않는 프로그래밍 기법이다.
Intersection Observer를 사용한 무한 스크롤 구현 IntersectionObserver 를 사용하면 특정 요소의 뷰포트에 타겟 요소가 들어왔는지를 판단할 수 있다.
1 const observer = new IntersectionObserver(callback, options);위와 같이 observer 객체를 생성할 수 있다. 생성자 함수에는 callback, options 두 가지 인자를 전달하는데 타겟 요소가 뷰포트 안으로 들어오면 콜백 함수를 실행하고 options 는 콜백 함수가 호출되는 조건을 설정할 수 있다.
callback
콜백 함수는 인자로 entries 와 observer 를 받는다. entries 는 IntersectionObserverEntry 라는 객체의 리스트라고 하는데 이 부분은 아직 이해하지 못했다. 예제를 보면 entries 를 받아 forEach 로 순회해 entry의 isIntersecting 값을 통해 타겟 요소가 뷰포트 내에 들어왔는지 확인한다. 무한 스크롤의 경우 이때 데이터를 불러오는 함수를 호출하면 될 것이다.
options
- root: 어떤 요소의 뷰포트에서 감지할지 설정한다. 기본값은 브라우저의 뷰포트이다.
- rootMargin: root 요소의 margin을 설정한다.
- threshold: 타겟 요소가 뷰포트에 얼마나 보일 때 콜백 함수를 실행할지 설정한다. 0~1 사이 값을 설정할 수 있으며 0일 경우 뷰포트에 타겟 요소가 1픽셀이라도 보이면 콜백 함수를 실행하고, 1일 경우 타겟 요소의 모든 픽셀이 뷰포트에 들어왔을 때 콜백 함수를 실행한다. 기본값은 0이다.
타겟 요소는 observer의 observe, unobserve 를 사용해 관찰을 시작하거나 중지할 수 있다.
1 observer.observe(target);2 observer.unobserve(target);
정리
무한 스크롤을 구현할 수 있는 방법을 정리해보았다. 예전에 무한 스크롤 구현하고 싶어서 스크롤 이벤트를 사용해 구현한 적이 있었다. 그때는 '이렇게 하는게 맞나?' 하는 생각이 있었는데 이번 기회에 정리할 수 있었다.
참고자료
https://developer.mozilla.org/ko/docs/Web/API/Intersection_Observer_API
https://heropy.blog/2019/10/27/intersection-observer/