image

모달 오픈 시 body 스크롤 방지 (이전 스크롤 위치 기억)

태그
ReactJavascript
상세설명모달 오픈 시 body 스크롤 방지 (이전 스크롤 위치 기억)
작성일자2023.12.20

이번에는 이전 스크롤 위치를 기억하면서 모달 창이 보이면 body 스크롤을 방지하는 방법에 대해 알아 보았다.

모달 창을 여는 index.tsx <ModalTest close={close} /> 로 close를 넘긴다.

//index.tsx
export default function Home() {
  const [modal, setModal] = useState(false);
  const showModal = () => {
    setModal(true);
  };

  const close = (x: any) => {
    setModal(x);
  };

  return (
    <>
      <Seo />
      <section css={HomePage}>
        {[1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13].map((x) => (
          <div key={x} className="HomeTop">
            <p className="HomeTilte" onClick={showModal}>
              Test {x}
            </p>
          </div>
        ))}
        {modal && (
          <div className="modal">
            <ModalTest close={close} />
          </div>
        )}
      </section>
    </>
  );
}

Modal.tsx에서 스크롤 방지와 스크롤 이전 위치를 기억하여 모달 창을 닫으면 이전 위치로 돌아간다.

preventScroll 함수를 통해 현재 위치를 반환하고 allowScroll 함수에 현재 위치를 넘긴다.

// Modal.tsx

import { useEffect } from "react";

export default function ModalTest(props: { close: (arg0: boolean) => void }) {
  const preventScroll = () => {
    const currentScrollY = window.scrollY;
    console.log(currentScrollY);
    document.body.style.position = "fixed";
    document.body.style.width = "100%";
    document.body.style.top = `-${currentScrollY}px`; // 현재 스크롤 위치
    document.body.style.overflowY = "scroll";

    return currentScrollY;
  };

  const allowScroll = (prevScrollY: number) => {
    document.body.style.position = "";
    document.body.style.width = "";
    document.body.style.top = "";
    document.body.style.overflowY = "";
    window.scrollTo(0, prevScrollY);
  };

  useEffect(() => {
    const prevScrollY = preventScroll();
    return () => {
      allowScroll(prevScrollY);
    };
  }, []);

  const setClose = () => {
    props.close(false);
  };

  return (
    <div>
      <p>Modal</p>
      <p onClick={setClose}>닫기</p>
    </div>
  );
}

코드 적용

참고