본문 바로가기
개발

iframe 내부 스크롤 위치 감지하기

by rious275 2023. 6. 1.

React에서 iframe 사용하기

iframe은 외부 파일을 중첩으로 삽입하는 것이기 때문에 별도의 환경으로 취급되어 React에서 일반적인 방법으로 컨트롤 할 수가 없지만, window.postMessage 메서드를 활용하면 상호작용 가능하다.

아래는 외부 html 파일을 삽입했고, 외부 파일의 스크롤을 감지하여 React 컴포넌트에 이벤트를 줘야하는 상황에 대한 해결책이다.

window.postMessage()

postMessage()는 다른 윈도우나 프레임으로 메시지를 안전하게 전달하는 데 사용되며, 부모와 자식 프레임, 또는 다른 도메인 간에도 통신할 수 있다. 두 가지의 매개변수가 있다.

1. message: 전송할 데이터: 문자열, 객체, 숫자 등 모든 형태 데이터
2. targetOrigin: 선택사항이며, 메시지를 받을 창의 도메인 지정

📌 적용

자식 컴포넌트(외부 html)

자식 페이지에서는 handleScroll 함수를 통해 문서의 스크롤 위치값(scrollTop)을 보낸다.

const { pageYOffset, parent, addEventListener } = window;

const handleScroll = () => {
  const options = {
    type: 'scrollPosition',
    payload: { scrollTop: pageYOffset || document.documentElement.scrollTop },
  };

  parent.postMessage(options, '*');
};

addEventListener('scroll', handleScroll);
handleScroll();

부모 컴포넌트(React)

부모 페이지에서는 useEffect안의 receiveMessage 함수를 통해 자식 페이지에서 보낸 scrollTop 데이터를 수신한다.

  useEffect(() => {
    const receiveMessage = (e: MessageEvent) => {
      if (e.data?.type === 'scrollPosition') {
        const scrollTop = e.data.payload.scrollTop;
        console.log(scrollTop)
      }
    };

    window.addEventListener('message', receiveMessage);
    return () => window.removeEventListener('message', receiveMessage);
  }, []);

위 로직을 통해 부모 페이지(React)에서 자식 페이지(iframe) 내부의 스크롤 위치를 받을 수 있고, 반대로 부모 페이지에서 자식 페이지으로 데이터를 보낼 때는 부모 페이지에서 postMessage를 사용 후 자식 페이지에서 해당 message를 수신하면 된다.