Intersection Observer
자주 사용할 것 같아서 한 번 정리해야 될 것 같았다.
Web API중 하나로
MDN을 참고하면 이렇게 되어 있다.
즉, Intersection observer
는 기본적으로 브라우저 뷰포트(Viewport)와 설정한 요소(Element)의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 포함되지 않는지, 더 쉽게는 사용자 화면에 지금 보이는 요소인지 아닌지 구별하는 기능을 제공한다.
사용이유
타겟이 화면에 노출 되었는지 여부를 간단하게 확인할 수 있는 API인데 만약 Intersection observer
를 사용하지 않고 기능 구현한다면 이벤트리스터를 이용해 스크롤이 일어날 때마다 체크를 하거나 등 성능이슈를 개선하기 위해 많은 노력을 했을것이다.
사용법
intersection observer
를 생성하기 위해서 생성자 호출 시 콜백 함수를 제공해야 함!
이 콜백함수는 threhold
가 한방향 혹은 다른 방향으로 교차 할 때 실행된다.
// 타겟 요소 관측 시, 실행될 콜백 함수
const callback = (entries, observer) => {
console.log('콜백함수');
};
// Observer 선언
const observer = new IntersectionObserver(callback, options);
// 타겟 요소 관측 시작
observer.observe(TargetElement);
// 타겟 요소 관측 중단
observer.unobserve(TargetElement);
// 모든 요소 관측 중단
observer.disconnect();
// 관측 중인 모든 요소를 배열 형태로 반환
observer.takeRecords();
Intersection Observer 에서 옵션객체는 말 그대로 옵션이기 때문에 선택사항이며 파라미터로 넘기지 않을 경우 기본 값이 적용된다.
intersection Observer 객체에서 사용 가능한 메서드
observe(파라미터로 targetElement)
파라미터로 넘긴 타겟 요소에 대한 관측을 담당한다. 동일한 옵저버 객체로 여러번 호출을 해서 다양한 타겟 요소에 대해 관측이 가능하다.
unobserve(파라미터로 targetElement)
타겟 요소에 대한 관측을 중지하는 역할을 담당.
disconnect
모든 타겟 요소에 대한 관측을 중지한다.
takeRecord
현재 관측 중인 모든 타겟 요소들을 배열 형태로 반환한다.
option
const option = {
root:null,
rootMargin: 0px,0px,0px,0px,
threshold:0
default 값으로만 구성된 option객체의 예시이다
그럼 이를 바탕으로 내 프로젝트에서 쓰일 무한 스크롤을 구현해보자
무한 스크롤 구현
const getPostList = async (page: number) => {
await axios
.get(`/posts/${page}`)
.then((res) => {
setPostListItem((snap) => [...snap, ...res.data]);
})
.catch((err) => console.log(err))
.finally(() => setLoading(false));
};
url의 경우 일단 프록시 미들웨어를 사용중이기 때문에 적지 않았고 받는 데이터 구분을 page로 구분하기 위해 page를 인자로 받는다.
getPostList
로 데이터를 불러왔다면, page
를 1씩 증가시켜서 그 다음 데이터를 불러오게 한다. 새롭게 불려진 데이터는 getPostList
를 통해 기존 데이터에 더해진다.loadMore
함수를 만들어 page
가 1씩 더해지는 함수를 만듬const loadMore = () => {
setPage(prev => prev + 1);
}
//...생략
<Loding />
로 해놨기에 ref
를 지정해놓고 탐색 타겟으로 정해놓는다.Intersection Observer
를 통해 뷰포트 내에 지정해둔 타겟<Loding/>
을 찾고 잇으면, loadmore
함수를 실행시켜 page
를 1씩 증가시킨다.const Main = () => {
...생략
useEffect(() => {
if (loading) {
//로딩되었을 때만 실행
const observer = new IntersectionObserver(
entries => {
if (entries[0].isIntersecting) {
loadMore();
}
},
{ threshold: 1 }
);
//옵져버 탐색 시작
observer.observe(pageEnd.current);
}
}, [loading]);
...생략
}
Reference
참고자료 1 - velog
참고자료 2 - velog