Slog
Sign in

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

2022 Aug 16
2 min read
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이 있는지 확인 후 수정하시면 되겠습니다!

Explore Popular Contents

0 Comments

Anonymous