이번에는 이전 스크롤 위치를 기억하면서 모달 창이 보이면 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> ); }
코드 적용
참고