progress bar 구현

황준승·2022년 4월 13일
0
post-thumbnail

목차

  1. 코드
  2. 코드 설명

1. 코드

2. 코드 설명

a) 브라우저의 요소 사이즈와 스크롤에 대한 이해

우리가 사용하는 자바스크립트는 브라우저의 요소의 높이나 너비를 계산해주는 관련 객체를 제공해줍니다.

프로그레스바 구현을 위해 document.documentElement 객체에 존재하는 스크롤 관련 속성을 이용하여 유저의 스크롤 위치를 계산하여 프로그레스바를 구현할 수 있었다.

이때 제가 사용한 속성은 scrollTop , clientHeight, scrollHeight 입니다.

1) scrollTop
내가 스크롤 하고 있는 위치를 나타내주는 요소라고 생각하면 된다.

2) clientHeight
스크롤바에 있는 컨텐츠 자체의 높이를 뜻합니다. 이 내부 높이는 padding의 값을 포함하고 있지만 margin영역은 포함하지 않습니다.

3) scrollHeight
수직 스크롤바를 사용하지 않고 요소의 컨텐츠를 모두 나타낼 때 필요한 최소 높이의 값과 동일합니다.

구현 방법

간단하게 생각해보면 전체 스크롤이 차지하는 높이에서 현재 내가 차지하고 있는 스크롤의 위치의 비율을 계산하여 css의 width에 적용시키면 쉽게 구현할 수 있다.

따라서 필자는 초반에

// 프로그레스바의 width
const width = ( scrollTop / scrollHeight ) * 100;  

으로 계산하였다.
하지만 이럴 경우 정확한 내 스크롤 위치를 나타내지 못하였다.

이 경우에 전체 scrollHeight의 높이에 컨텐츠 길이(clientHeight)가 포함된 길이이기 때문에 전체 스크롤의 길이을 알고 싶다면 scrollHeight - clientHeight를 해주어야 한다.

const { scrollTop, scrollHeight, clientHeight } = document.documentElement; 

const height = scrollHeight - clientHeight
const width = ( scrollTop / height ) * 100;

// css 스타일 적용
document.querySelector(`.${className}`).style.width = `${width}%`;

b) 디바운스와 스로틀

평소 디바운스와 스로틀을 구현할 때 timer의 여부를 판단하기 위해 전역변수로

let timer;

이렇게 두는 것이 굉장히 불편했다.

따라서 이번 미니프로젝트에서 이런 전역변수를 제거하고 모듈화를 할 수있도록 하기 위해서 클로저를 사용하여 디바운스와 스로틀을 구현해보았다.

코드 (util/debounceAndThrottle.js)

export const throttleAndDebounce = () => {
  // 쓰로틀링과 디바운스를 체크하기 위한 변수를 만들어줍니다.
  let throttleCheck, debounceCheck;

  return {
    // throttle과 debounce 모두 실행할 콜백 함수와 실행할 주기를 인자로 받습니다.
    throttle(callback, milliseconds) {
      return function () {
        if (!throttleCheck) {
          // setTimeout을 이용하여 설정한 주기마다 콜백이 실행될 수 있도록 하였고,
          // 실행이 끝난 후에는 다시 throttleCheck를 false로 만들어 주어, 설정한 주기마다 이벤트가 한 번씩만 호출되도록 하였습니다.
          throttleCheck = setTimeout(() => {
            callback(...arguments);
            throttleCheck = false;
          }, milliseconds);
        }
      };
    },

    debounce(callback, milliseconds) {
      return function () {
        // clearTimeout을 이용하여 이벤트 발생을 무시해주고,
        // 마지막 호출 이후, 일정 시간이 지난 후에 단 한 번만, 이벤트가 호출되도록 하였습니다.
        clearTimeout(debounceCheck);
        debounceCheck = setTimeout(() => {
          callback(...arguments);
        }, milliseconds);
      };
    }
  };
};

throttleAndDebounce를 실행하게 되면 throttleCheckdebounceCheck 변수를 사용할 수 있게 되고 추가적으로 내부 함수 실행을 통한 callback함수 실행 지연도 가능하게 해줄 수 있습니다.

그 외

react 스럽게 개발하기 위해 SPA어플리케이션 형식으로 개발하였습니다;;

참고자료

profile
다른 사람들이 이해하기 쉽게 기록하고 공유하자!!

0개의 댓글