앞 글에서 정리했던 JS에 IntersectionObserver 기능을 React에 적용 해보았다.
React에 Intersection Observer API가 있다는 데 봐도 어떻게 사용하는 건지 잘 모르겠어서 JS와 useRef를 섞어서 구현해보았다.
const introRef = useRef(null);
const guideRef = useRef(null);
useEffect(() => {
let introObserver = new IntersectionObserver((e) => {
// e : 현재 감시 중인 모든 div 박스가 출력됨
e.forEach((box) => {
// 감시 중인 box가 등장 & 퇴장 시 실행됨 => 이중으로 동작함
// 화면에 보일 때만 style을 변경하고 싶을 때는
if (box.isIntersecting) {
box.target.style.opacity = 1;
// intro 자식 중에 한 부분을 선택해서 또다른 intersectionObserver 연결함
if (e[0].target.className === "content_6") {
Array.prototype.forEach.call(guideRef.current.children, (child) => {
// .observe() : HTML 요소가 화면에 등장하는 지 감시해 주는 역할
// 파라미터에 HTML 요소를 넣어주면 된다.
guideObserver.observe(child);
});
}
} else {
box.target.style.opacity = 0;
}
});
});
let guideObserver = new IntersectionObserver((e) => {
e.forEach((box2) => {
if (box2.isIntersecting) {
box2.target.style.background = "#f2f4f6 0% 0% no-repeat padding-box";
} else {
box2.target.style.background = "white";
}
});
});
Array.prototype.forEach.call(introRef.current.children, (child) => {
introObserver.observe(child);
});
}, []);
이중 IntersectionObserver 사용한 이유
introObserver는 소개 페이지 안에서에 스크롤 애니메이션이고,
guideObserver는 소개 페이지 중에서도 특정 가이드 부분에 스크롤 애니메이션을 넣은 코드이다.
그래서 introObserver 콜백 함수 안에 if문을 넣어서 content_6(특정 부분)일 때 guideObserver.oberserve()를 실하도록 설정했다.
Array.prototype.forEach.call(ref, () => {});를 사용한 이유
ref.current.children을 콘솔로 찍어보면 HTMLCollection으로 출력되는 걸 볼 수 있는 데 HTMLCollection은 filter, forEach와 같은 Array 함수 기능을 제공하지 않기 때문에 Array.prototype에 바인딩하여 자식들을 출력하였다.
(아래 사이트 참고함)
비교
+ 추가로 기존에 구현했던 window.addEventListener("scroll", handleScroll);도 intersectionObserver로 변경 해보았다.
위 예제와 다른 점이라면 "ref에 style을 변경하였는가", "state에 따라 className을 부여하여 style을 변경하였는가"일 것 같다.
(🥸 React는 document를 직접 건드리면 안되기 때문에 주로 state 값에 따라 className을 부여하여 style을 변경한다.)
useEffect(() => {
let footerObserver = new IntersectionObserver((e) => {
e.forEach((box3) => {
if (box3.isIntersecting) {
setBottomState(false);
} else {
setBottomState(true);
}
});
});
Array.prototype.forEach.call(footerRef.current.children, (child) => {
footerObserver.observe(child);
});
}, []);
사용 후기
뭔가 소개 페이지가 더 다이나믹 해지면서 공을 들인 느낌이 나는 것 같다. 다음에는 intersectionObserver를 사용하여 무한 스크롤 기능도 만들어 봐야겠다. 기능 공부는 아주 즐거워☺️
'더 알아보기 > 기능' 카테고리의 다른 글
Pagination 만들기 (라이브러리 X) (0) | 2022.11.09 |
---|---|
반응형 사이드바 구현하기 (0) | 2022.11.07 |
[JS] IntersectionObserver 사용해보기 (0) | 2022.11.04 |
[React] 날짜, 시간 선택 달력 만들기 (ver.시행착오) (0) | 2022.10.13 |
[React] 버튼 눌러서 프린트 출력하기 (0) | 2022.09.14 |
댓글