IntersectionObserver 정리 및 결과물

Blackpepper·2024년 8월 20일

IntersectionObserver은 관찰중인 DOM 요소가 뷰포트와 교차하고 있는지 감지하는 API다. 생성자와 4가지 함수를 가지고 있다.

new IntersectionObserver(callback[, options]);

mutationObserver나 resizeObserver와 같이 생성자에 콜백함수를 등록한다.

콜백함수의 인자로 감시하는 DOM 요소 중 지정한 역치를 넘어가게 된 요소의 배열과 콜백을 호출한 intersectionObserver 그 자체를 넘긴다.

option으로는 root, rootMargin, threshold를 지정할 수 있고, 지정하지 않으면 문서 뷰포트를 루트로, 여백 없이, 0% 역치로 설정한다.

root 는 대상 요소의 조상 DOM을 지정할 수 있다.

rootMargin은 CSS margin 속성과 유사한 값을 받을 수 있고, 루트 영역의 크기를 키우거나 줄이고자 할 때 사용한다. (기본값 : 0px 0px 0px 0px)

threshold는 대상이 보이는 영역과 전체 바운딩 박스의 비율에 대한 역치를 나타낸다. 0.0으로 지정하면 대상 픽셀이 하나라도 보이면 대상을 볼수 있는 것으로 취급하고, 1.0이면 대상 픽셀이 전부 보여야 대상을 볼 수 있는 것으로 취급한다.

아래는 IntersectionObserver를 사용하여 무한 스크롤을 구현한 방식이다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Infinite Scroll with IntersectionObserver</title>
    <style>
        .item {
            height: 100px;
            margin: 10px 0;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 24px;
        }
        #loading {
            text-align: center;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div id="container"></div>
    <div id="loading">Loading...</div>

    <script>
        function createItems(count) {
            const container = document.getElementById('container');
            for (let i = 0; i < count; i++) {
                const item = document.createElement('div');
                item.className = 'item';
                item.textContent = `Item ${container.children.length + 1}`;
                container.appendChild(item);
            }
        }

        createItems(10);

        const observer = new IntersectionObserver(entries => {
            const lastItem = entries[0];
            if (lastItem.isIntersecting) {
                createItems(10);
            }
        }, {
            rootMargin: '0px 0px 200px 0px'
        });

        observer.observe(document.getElementById('loading'));
    </script>
</body>
</html>
profile
까만 연미복의 남자

0개의 댓글