IntersectionObserver (Web API) - 스크롤 영역 벗어나면 자동으로 닫히는 툴팁

옹잉·2026년 3월 6일

✨ 알게된 것

목록 보기
8/8

툴팁 버튼 컴포넌트를 만들었는데
테이블에서 스크롤 시 툴팁이 닫히지 않는 문제가 있었다.
TableBody 영역을 벗어났을 때 툴팁이 닫히도록 IntersectionObserver를 사용해 해결했다.

 useEffect(() => {
    if (!isOpen || !buttonRef.current) {
      return;
    }

    const observer = new IntersectionObserver( // 1. 감시자 생성
      ([entry]) => { // 버튼 상태 감지
        if (!entry.isIntersecting) { // 스크롤로 버튼이 안보이면
          setIsOpen(false); // 툴팁 닫기
        }
      },
      {
        root: buttonRef.current?.closest('.overflow-y-auto'), // 기준 영역 = 스크롤 컨테이너
        threshold: 0, // 1px이라도 벗어나면 감지
      }
    );

    observer.observe(buttonRef.current); // 2. 감시 대상 등록 (버튼 감시 시작)
    return () => observer.disconnect(); // 3. 감시 중단 (isOpen 바뀌거나 언마운트 시 감시 중단)
  }, [isOpen]);

IntersectionObserver란?

특정 요소가 지정한 영역(root)에 보이는지 안보이는지를 감시하는 브라우저 API

root (스크롤 컨테이너)
┌─────────────────┐
│                 │
│  [버튼] ← 보임 	  │  → isIntersecting: true
│                 │
└─────────────────┘
   [버튼] ← 스크롤로 밖으로 나감 → isIntersecting: false

entry란?

observer가 감시하는 요소 하나하나의 상태 정보

const observer = new IntersectionObserver(
  (entries) => {
    // entries = 감시 중인 요소들의 상태 배열
    // observer.observe(buttonRef.current) 하나만 등록했으니
    // entries[0] = 버튼 상태
    const entry = entries[0]; // = ([entry]) 구조분해

    entry.isIntersecting  // 보이면 true, 안보이면 false
    entry.target          // 감시 대상 DOM 요소 (버튼)
    entry.intersectionRatio // 얼마나 보이는지 비율 (0.0 ~ 1.0)
  }
);

참고) 공식문서 - IntersectionObserver

profile
틀리더라도 🌸🌈🌷예쁘게 지적해주세요💕❣️

0개의 댓글