[javascript] body 스크롤 막기

hyejinJo·2023년 12월 7일
0

Javascript / jQuery

목록 보기
8/8

스크롤 기능을 막아야하는 상황에서 대부분은 body 에 overflow-y: hidden 을 주는 방법이 제시되지만, 그렇지 않은 경우 자바스크립트로 이를 처리해야한다.

처음엔 아래와 같이 이벤트를 주었지만 작동하지 않았다 ㅠ

$body.addEventListener('scroll', function(e) {
    e.preventDefault();
  })

두번째 시도로 아래와 같이 다른 이벤트에도 적용해보았지만 작동은 하지 않고 에러까지 발생했다.

const $body = document.querySelector('body');
  function preventScroll(e) {
    e.preventDefault();
  }

  $body.addEventListener('scroll', preventScroll);
  $body.addEventListener('touchmove', preventScroll);
  $body.addEventListener('mousewheel', preventScroll);

구글링을 해보니 passive: false 옵션을 추가해주면 된다고 한다. 그런데 mousewheel 이벤트와 같이 스크롤과 관련된 이벤트는 기본적으로 passive로 처리되어 추가 옵션을 설정할 수 없었다.

대신, wheel 이벤트를 사용하여 스크롤을 감지하고 preventDefault를 호출하면서 성능 최적화와 문제 해결을 동시에 할 수 있었다.

const $body = document.querySelector('body');
  function preventScroll(e) {
    e.preventDefault();
  }
  // 'wheel' 이벤트를 사용하여 스크롤 감지 후 방지
  $body.addEventListener('wheel', preventScroll, { passive: false });
  $body.addEventListener('click', function() { // body 를 다시 클릭하면 스크롤 재개
    $body.removeEventListener('wheel', preventScroll, { passive: false });
  });

passive옵션을 추가하고 wheel 이벤트로 바꾸었더니 body 스크롤링이 잘 멈추었다.

wheel 이벤트와 scroll, mousewheel 의 차이, 그리고 성능최적화에 대한 내용이 더 궁금하여 챗지피티에 물어보니, 내용은 다음과 같았다.

wheel 이벤트는 마우스 휠 또는 트랙패드 등 더 다양한 입력 장치에서 발생하는 스크롤 이벤트로, mousewheel 이벤트와 비슷하지만wheel 이벤트가 표준에 더 가깝고 여러 입력 장치에서의 일관성을 제공한다고 한다.

wheel 이벤트가 passive로 처리되는 것은 브라우저가 성능 최적화를 위해 도입한 개념 중 하나이고, 브라우저는 기본적으로 wheel 이벤트에 대해 passive 플래그를 설정하여 이벤트 리스너 내에서 preventDefault를 호출하는 것이 불가능하도록 만들어준다.

passive 플래그가 설정된 이벤트 리스너에서 preventDefault를 호출하는 것은 브라우저가 스크롤링 동작을 최적화하기 위해 이벤트 핸들러를 비동기적으로 실행하도록 허용하게 되는데, 이로 인해 호출 순서가 보장되지 않기 때문에 스크롤을 막아야 하는 경우에는 passive: false로 설정된 이벤트 리스너를 사용해야 한다..!


참고: https://solbel.tistory.com/1299
profile
FE Developer 💡

0개의 댓글