: 스크롤이나 클릭 등, 이벤트를 실행시킬 때 브라우저의 성능을 위해 쓰는 API.
<html>
<body>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<script>
window.addEventListener("scroll", (event) => {
const boxes = document.querySelectorAll(".box");
boxes.forEach((box)=>{
const rect = box.getBoundingClient();
})
});
</script>
</body>
</html>
우리는 위의 코드처럼 박스들의 정보를 스크롤할때마다 얻을 수 있다. 하지만 저것은 좋은 코드가 아니다. 왜냐하면 콜백함수는 브라우저에서 특정한 이벤트가 발생할때 수행되는데, 수행되는것은 main thread(UI thread) 위에서 동작한다. 그래서 저 콜백함수가 실행하는 동안 다른 일을 할 수 없다(동기적).
예를 들어서 저 콜백함수가 실행되는 동안 클릭하는 이벤트를 눌러도 클릭이벤트는 실행될 수 없다. 그래서 이벤트에 등록하는 함수들은 최대한 가볍고 성능이 간단한 것을 등록하는것이 좋다.
다시 코드를 자세히 보면, 각각의 박스들을 돌면서 즉, 매번 boxes의 배열을 돌면서 각각의 요소의 getBoundinClient 정보를 얻기 위해서는 브라우저 위에서 DOM요소에 레이아웃이 발생한다. 그리고 페이지에서 레이아웃이 계속 발생하니까 성능이 좋지 않다. 클릭이 될때마다 이러한 레이아웃이 발생하는것도 좋지 않은데 하물며 스크롤은 더욱 많이 발생하므로 저렇게 쓰는 것은 좋지 않다. 660번 스크롤 하게 되면 660번의 콜백함수가 실행되고 660개의 DOM요소가 만들어지고 레이아웃이 그만큼 발생하니까! 게다가 box가 아니라 일반 섹션이나 각각의 사이즈가 다른 요소들이 반복되어진다면 전역변수로 box들을 미리 지정해도 소용없다.
그래서 이때를 위해 쓰는 것이
"ItersectionObserver() API" !!
-> 비동기적으로 어떤 변화를 감지하는 API이다. 어떤 요소가 부모 컨테이너 안이나 윈도우(뷰포트) 전체 창 안에서 요소의 Intersection을 감지한다. 즉, 요소가 창 안이나 부모 안에서 교차가 되는지를 확인하는 API. 만약 문서가 자체가 엄청 길지만 뷰포트로 보는건 제한적인 상태라면, 사용자에게 보여지는 부분만 DOM요소에서 삭제했다가 사용자가 스크롤링할 때 다시 DOM요소에 등록해서 보여줄 수 있는 경우, 등 유용하게 쓰이는 API이다.
// 위의 코드를 이용해서 IntersectionObserver() api 사용하기
<html>
<head>
<style>
.box {
width: 300px;
height: 300px;
background-color: yellow;
}
.box.active {
background-color: purple;
}
</style>
</head>
<body>
<div class="box>1</div>
<div class="box>2</div>
<div class="box>3</div>
<div class="box>4</div>
<div class="box>5</div>
<div class="box>6</div>
<div class="box>7</div>
<div class="box>8</div>
<div class="box>9</div>
<div class="box>10</div>
<script>
const boxes = document.querySelectorAll(".box");
const options = {
root: null, // deafult값 (뷰포트)
rootMargin: '100px 10px 10px 10px', // '0px'- deafult값
threshold: 0, // '0' = deafult값
}
const callback = (entries, observer) => {
entries.forEach(entry) => {
if(entry.isIntersecting) {
entry.target.classList.add("active");
} else {
entry.target.classList.remove("active");
}
})
}
const observer = new IntersectionObserver(callback, options);
boxes.forEach(box => observer.observe(box));
</script>
</body>
</html>
IntersectionObserver()에서 등록한 콜백함수의 인자에 entries, observer을 넣어 원하는 정보를 얻을 수 있다. entries를 살펴보면 배열 안에 IntersectionObserverEntry를 볼 수 있는데 이것은 화면에 들어온 요소의 정보를 담고 있다. 이 오브젝트를 다시 들여다보면 프로퍼티들을 확인할 수 있는데,
여러 정보를 알 수 있다.
그래서 저 정보들을 바탕으로 entry.isIntersecting가 true일 때, 즉 요소가 안에 들어온 상태라면 active 클래스가 붙어서 보라색으로 박스색깔이 변한다.
그리고 옵션도 설정 할 수 있다. (options)
출처
드림코딩아카데미 포트폴리오웹사이트클론코딩을 보고 정리