프로젝트 중 스크롤 막기 구현

hoin_lee·2023년 3월 7일
0

TIL

목록 보기
159/236

프로젝트를 진행 중 만들기 모달을 만들다가 스크롤 하는 과정에서 배경화면이 스크롤 되어 아주 거슬리는 부분이 있었다.
그래서 진행하던 중 약 2가지 방법을 찾아냈다.

  1. 직접 body 스타일에 접근하여 fixed를 통한 고정과 top을 이용하여 현재 머무르고 있는 위치로 그대로 붙도록 하는 것이다.
useEffect(() => {
    document.body.style.cssText = `
      position: fixed; 
      top: -${window.scrollY}px;
      overflow-y: scroll;
      width: 100%;`;
    return () => {
      const scrollY = document.body.style.top;
      document.body.style.cssText = ``;
      window.scrollTo(0, parseInt(scrollY || "0", 10) * -1);
    };
  }, [])

하나하나 설명해 보자면 일단 useEffect를 통해 모달창이 렌더링 즉 마운트 될때 bodycss를 변경시킨다.
실행 될 때body값이 fixed로 고정되며 top이 현재 보고 있는 스크롤에 붙을 수 있도록 window.scrollY로 현재 보고 있던 위치에 고정한다
overflow-yscroll로 놓아 스크롤이 사라져 화면 비율이 변하는 것을 막는다.
이후 return(clean up함수로 useEffect를 정리해준다. deps가 비어있으니 컴포넌트가 사라질 때 동작)을 통해 모달 창에 사라질 때 미리 스크롤링 하던 현재 바디 위치를 미리 scrollY에 저장하고 body의 css를 비워준다.
(위의 예제는 빈 값이지만 나는 body에 정한 css가 있었어서 해당 css로 변경시켰다.)
이후 window.scrollTo를 이용해 모달이 종료되었을 때 해당하는 스크롤에 그대로 있을 수 있게 한다.

출처: 스크롤 고정 출처

  1. 스크롤 방지 이벤트를 커스텀 훅으로 만들어서 사용하는 방법이었다. 이는 구글링을 통해 찾았는데 해당 코드를 보면
import { useRef } from "react";

export default () => {
  const scroll = useRef(false);

  const blockScroll = () => {
    if (typeof document === "undefined") return;

    const html = document.documentElement;
    const { body } = document;

    if (!body || !body.style || scroll.current) return;

    const scrollBarWidth = window.innerWidth - html.clientWidth;
    const bodyPaddingRight =
      parseInt(
        window.getComputedStyle(body).getPropertyValue("padding-right")
      ) || 0;

    /*
     * 1. iOS 및 데스크톱 사파리의 버그 수정으로 설정 {overflow: hidden}은
     * html/body에서 스크롤을 방지하지 않는다. *
     * 2. {overflowY}가 방지하지 않는 데스크톱 사파리에서 버그 수정 *
     * {overflow-x} 스타일이 본문에도 적용되는 경우 스크롤
     */
    html.style.position = "relative"; /* [1] */
    body.style.position = "relative"; /* [1] */
    html.style.overflow = "hidden"; /* [2] */
    body.style.overflow = "hidden"; /* [2] */
    body.style.paddingRight = `${bodyPaddingRight + scrollBarWidth}px`;

    scroll.current = true;
  };

  const allowScroll = () => {
    if (typeof document === "undefined") return;

    const html = document.documentElement;
    const { body } = document;

    if (!body || !body.style || !scroll.current) return;

    html.style.position = "";
    html.style.overflow = "";
    body.style.position = "";
    body.style.overflow = "";
    body.style.paddingRight = "";

    scroll.current = false;
  };

  return [blockScroll, allowScroll];
};

앞서 useEffect를 사용한 것과 내용은 거의 비슷하다. 똑같이 body와 html을 구한 후 css들을 변경하여 진행한 것이다.

출처 - 스크롤 고정 커스텀 훅-typescript

profile
https://mo-i-programmers.tistory.com/

0개의 댓글