iOS 디바이스 에서 body 스크롤을 막는 방법

3개월 전·수정됨
iOS 디바이스 에서 body 스크롤을 막는 방법

iOS 디바이스에서 body의 스크롤을 완벽하게 막기 위한 시행착오와 방법을 설명하려합니다.
일주일 정도 삽질한 끝에 효과적인 솔루션을 찾았습니다. 😂

배경

not working

iOS Sarafi 에서는

body { overflow: hidden; }

로 body의 스크롤이 막히지 않습니다.

그렇기 때문에 다른 방법을 시도해야만 했습니다.

시도한 방법

검색해서 찾아보니 주로 body-scroll-lock 을 많이들 사용하시는데, 치명적 단점이 존재했습니다.

import { disableBodyScroll } from 'body-scroll-lock'; const Component = () => { const disableScroll = () => disableBodyScroll(document.querySelector('.modal')); return ( <div className="modal"> <span>This is Content.</span> <div className="scroll" style={{ overflow: 'auto' }}> <p>Scroll is not working</p> </div> </div> ); };

위와 같이 disableBodyScroll 의 인자로 넘긴 요소는 스크롤이 잘 되는데
그 하위 요소인 .scroll 요소는 스크롤이 되지 않는 것이었습니다.

결국 해당 라이브러리를 사용할 수 없었고, 다른 방법을 찾았습니다.

해결 방법

방법결과
touch-move: none;동작하지 않음.
pointer-events: none;동작하지 않음.
body.addEventListener('touchmove', (e) => e.preventDefault());모달 내부 요소도 스크롤이 안됨.
npm body-scroll-lock인자로 넘긴 element의 하위요소는 스크롤 안됨.
position: fixed;정상 작동함.

해결한 방법은 body에 position: fixed; 를 주는 것이었습니다.

// 스크롤 잠금 const enableScrollLock = () => { const { body } = document; if (!body.getAttribute('scrollY')) { const pageY = window.pageYOffset; body.setAttribute('scrollY', pageY.toString()); body.style.overflow = 'hidden'; body.style.position = 'fixed'; body.style.left = '0px'; body.style.right = '0px'; body.style.bottom = '0px'; body.style.top = `-${pageY}px`; } }; // 스크롤 잠금 해제 const disableScrollLock = () => { const { body } = document; if (body.getAttribute('scrollY')) { body.style.removeProperty('overflow'); body.style.removeProperty('position'); body.style.removeProperty('top'); body.style.removeProperty('left'); body.style.removeProperty('right'); body.style.removeProperty('bottom'); window.scrollTo(0, Number(body.getAttribute('scrollY'))); body.removeAttribute('scrollY'); } };

body 요소를 fixed로 고정되면서 스크롤을 막습니다.

여기서 중요한 포인트는 top 을 -window.pageYOffset 만큼 줘서 fixed로 변경하였지만 변경하지 않은 것 처럼 보이게 하는 것입니다.

스크롤 잠금을 해제할 때는 fixed가 풀리면서 스크롤이 상단으로 이동되는데, window.scrollTo를 통해 바로 스크롤을 내려주면 자연스럽게 스크롤을 잠그고 해제가 가능합니다.

주의사항

body 에 position: fixed 를 주고 top 으로 강제로 위로 올려버리기 때문에 다른 요소에 position: fixed 가 있지만 top이나 bottom 속성을 주지 않으면 body와 함께 top: -window.pageYOffset 만큼 올라가버립니다.

그렇기 때문에 다른 fixed 요소에 top 혹은 bottom이 있는지 확인 후 수정하시면 되겠습니다!

댓글 0