[JavaScript] 레이어 팝업 스크롤 막기

function_dh·2020년 12월 3일
post-thumbnail

설명

팝업이 열릴 때 브라우저의 스크롤을 방지하기 위해 흔하게 사용하는 방법으로 css를 활용하여 body에 overflow:hidden을 적용 시킵니다. 방법도 간편하고 스타일로 제어할 수 있기 때문에 많이 사용하지만 ios safari에서 동작하지 않는 문제가 있기 때문에 추가적으로 작업을 해야합니다.

// 기존 팝업 스크롤 방지
const body = document.querySelector('body');
body.style.overflow = 'hidden'

position:fixed를 활용한 방법

여러 방법이 있지만 현재 가장 활용도가 높은 방법은 position을 활용하여 현재 이동한 스크롤의 높이값 만큼 body를 고정 시키는 방법입니다.

스크롤의 높이값을 구하는 건 window.pageYOffset를 활용하여 현재 페이지의 스크롤을 내린 만큼 값을 구할 수 있습니다. 추가로 설명을 하자면 window.pageYOffset은 scrollY와 똑같은 기능을 하지만 하위 브라우저도 지원을 하기 때문에 크로스 브라우징을 생각한다면 pageYOffset을 활용하는 것이 좋습니다.

// 현재 페이지에서 스크롤을 내린만큼 값을 저장
let scrollPosition = 0;
scrollPosition = window.pageYOffset;

해당 스크롤의 위치값을 구했다면 body의 position:fixed를 주고 위치 값을 지정할 때 top에 스크롤의 위치값 만큼 값을 빼줍니다. 값을 빼주지 않으면 top:0으로 되어 스크롤이 최상단으로 올라가게 처리 됩니다!

// 저장된 스크롤의 위치값 만큼 빼주자
const body = document.querySelector('body');
body.style.top = `-${scrollPosition}px`;

마무리로 body의 width:100% 설정(position:fixed가 설정 되면서 기존 display:block의 width값이 사라지기 때문)과 팝업을 닫을 때 설정 했던 css 속성 값을 삭제해주면 아래와 같은 코드가 됩니다.

예시

const body = document.querySelector('body');
let scrollPosition = 0;

// 팝업 오픈
function enable() {
  scrollPosition = window.pageYOffset;
  body.style.overflow = 'hidden';
  body.style.position = 'fixed';
  body.style.top = `-${scrollPosition}px`;
  body.style.width = '100%';
}
// 팝업 닫기
function disable() {
  body.style.removeProperty('overflow');
  body.style.removeProperty('position');
  body.style.removeProperty('top');
  body.style.removeProperty('width');
  window.scrollTo(0, scrollPosition);
}

팝업을 닫을 때 보통 선언했던 css 속성을 초기화 시켜 원래 상태로 되돌리는데 removeProperty 메소드를 활용하면 초기화 시키지 않고 해당 스타일을 쉽게 제거할 수 있습니다. 그리고 마지막에 스크롤의 위치를 이동 시킬 수 있는 window.scrollTo(X축, Y축) 메소드를 활용하여 팝업 오픈때 저장한 스크롤의 위치값 만큼 스크롤을 이동시켜 body의 position이 해제 됐을 때 최상단으로 이동하는 걸 방지할 수 있습니다.

이슈

스크롤 잠금이 활성화 된 상태에서 브라우저 창의 크기를 변경하면 처음 저장 했던 스크롤의 높이와 달라 지기 때문에 스크롤 위치가 올바르게 복원되지 않는 단점이 존재합니다. 하지만 그 외에 사용 했을 때 문제점을 따로 발견하지는 못했습니다.

참고 사이트

Simple Solution to Prevent Body Scrolling on iOS

profile
🍄 성장형 괴물..

0개의 댓글