- Published on
Intersection Observer를 이용한 Scroll 애니메이션
- Authors

- Name
- dwook
Instersection Observer
이전에는 scrollTop, getBoundingClientRect() 등을 사용
이전 스크롤 이벤트의 문제점
- 스크롤을 하면 다수의 스크롤 이벤트 발생. debounce등의 작업 필요.
- getBoundingClientRect() 호출 시 리플로우 작업으로 성능저하 발생
polyfill을 사용해야하나 모던 웹브라우저 대부분은 지원
타겟과, 타겟의 부모나 뷰포트가 교차하는 부분의 변화를 비동기로 관찰하는 API
메인스레드에서 계속 교차를 확인하는 대신 교차가 일어날 때 인자로 넘겨준 콜백함수를 실행
옵션
root: 타겟이 보이는지 결정하는 타켓의 부모 또는 뷰포트. 타겟의 상위 엘리먼트여야 하고 기본값은 브라우저의 뷰포트.rootmargin: root의 margin으로 사용할 값. 기본값은 0이고, px나 %.threshold: 타겟이 얼만큼 보여야 콜백함수를 실행할지 결정하는 값. number 또는 array. 0.3는 타겟이 30% 노출되었을 때 이벤트 실행. array는 각각의 비율로 노출될 때마다 함수가 실행.
기본
html
<div class="animation" data-delay="0s">
<div class="animation" data-delay=".5s">
<div class="animation" data-delay=".7s">
<div class="animation" data-delay="1s">
css
.animation {
opacity: 0; /* 0으로 시작해야 없다가 나타나는 형태 */
}
@keyframes animation {
from {
transform: translateY(-100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
js
// 애니메이션 요소 1개
const target = document.querySelector('.animation');
// 1단계: observer 인스턴스 생성
const observer = new IntersectionObserver((entries) => {
if(entries[0].intersectionRatio > 0) {
entries[0].target.style.animation = `animation 2s forwards ease-out`;
} else {
entries[0].target.style.animation = 'none';
}
}, options);
// 2단계: observe 메서드에 target을 넘김.
observer.observe(target);
js
// 애니메이션 요소 여러개
const targetList = document.querySelectorAll('.animation');
const bserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if(entry.intersectionRatio > 0) {
entry.target.style.animation = `animation 2s ${entry.target.dataset.delay} forwards ease-out`;
}
else {
entry.target.style.animation = 'none';
}
})
}, options);
targetList.forEach(target => {
observer.observe(target)
});
Hook
참조링크