본문 바로가기
css

JavaScript 페이지 스크롤 진행률 표시줄

by code-box 2022. 1. 13.
반응형

페이지 상단에 진행률 표시줄이 있는 여러 블로그/뉴스 기사 웹 사이트를 발견했을 것입니다. 이 웹 사이트는 페이지 전체를 스크롤하면서 계속 변경됩니다. 여기서 HTML, CSS, 간단한 자바스크립트를 사용하여 구현하는 방법을 알아보겠습니다.

여기서 코드펜에 직접 접속할 수 있습니다.

Example Image

먼저 HTML 마크업의 본문 태그 바로 뒤에 id progressBar가 있는 빈 div를 추가합니다. 이 표시는 페이지 상단에 고정될 것입니다. 이를 위해 CSS 속성을 추가해 보겠습니다.

 
<div class="progressBar"></div>

div는 처음에 비어 있으므로 표시기 너비의 변경 사항은 전체 div 너비(진행 표시줄이라고도 함)에 영향을 미칩니다. 너비:0부터 시작하여 JavaScript를 사용하여 전체 페이지를 스크롤할 때 이 너비의 스타일을 계산하고 다양화할 것입니다.

.progressBar {
          position: fixed;
      top: 0;
      left: 0;
      height: 8px;
      background: linear-gradient(to right, #ff5f6d, #ffc371);
      width: 0%;
          z-index: 100;
      transition: width 0.2s ease-out;
}

자바스크립트를 추가하여 재미있는 부분에 대해 이야기해보자.

진행 표시줄 ID와 섹션 선택기를 선택합니다. 그런 다음 지정된 선택기와 일치하는 문서 내의 첫 번째 요소를 반환하는 문서 메서드 querySelector()의 매개 변수로 전달합니다.

 
const progressBar = document.querySelector('.progressBar');
const section = document.querySelector('section');

이제 몇 가지 계산을 수행하는 scrollProgressBar라는 화살표 함수를 선언합니다. scrollDistance는 횡단면의 크기와 뷰포트에 상대적인 위치를 정의합니다. 우리의 경우에는 맨 위 거리만 필요하기 때문에 section.getBoundingClientRect()라고 씁니다. 우리는 이 값을 나중에 백분율로 변환해야 하므로 양의 값이 가장 적합할 것입니다.

let scrollDistance = -(section.getBoundingClientRect().top);

우리는 좋은 옛날 Math.abs() 방법을 사용하여 꼭대기의 절대값을 반환할 수 있었는데, 대신 음수(-ve) 값을 가져와서 양의 값으로 변환할 것이다. 스크롤 막대에 대한 추가 논리를 구현하는 동안 그 이유를 알아보겠습니다.

Viewport Image

 

완전한 직사각형이 웹사이트의 뷰포트라고 상상해보세요. 처음에 진행률 표시줄의 너비가 0인 경우 뷰포트는 웹 페이지의 맨 위에 남아 있습니다. 웹 페이지를 충분히 스크롤할 수 있으면 페이지 길이가 뷰포트 높이를 초과하고 worklProgressBar 기능이 시작됩니다.

그런 다음 다음 공식을 사용하여 progressPercentity를 계산합니다.

여기서 분자는 이미 스크롤된 웹 페이지 거리를 나타내며 분모는 웹 페이지 끝에 도달하기 위해 남은 스크롤 거리를 정의합니다.

Progress Percentage Formula

  • 이제 뷰포트 높이가 상단 뷰포트 높이이므로 실제로 페이지 하단에 도달하지 않는다는 문제가 발생할 수 있습니다. 따라서 단면 높이에서 문서 높이를 빼야 합니다.
  • 이 부분을 100으로 곱하면 결국 진행률 표시줄에 대한 백분율 인덱스가 생성됩니다.
  • Math.floor()를 적용하면 십진수 값보다 작거나 같은 가장 큰 정수가 반환됩니다.
 
let progressPercentage =(scrollDistance/(section.getBoundingClientRect().height - document.documentElement.clientHeight)) * 100;

let val = Math.floor(progressPercentage);

이 val의 도움으로 HTML DOM(JavaScript가 HTML 요소의 스타일을 변경할 수 있음)을 사용하여 진행 표시줄의 너비 스타일을 % 기호와 연결하여 계산합니다.

progressBar.style.width = val + '%';

이벤트 수신기에 스크롤 이벤트를 추가하면 사용자가 페이지를 스크롤할수록 진행률 표시줄 너비가 증가합니다.

window.addEventListener('scroll', scrollProgressBar);
 

지금까지 Math.abs()를 사용하는 것이 왜 좋은 생각이 아님을 깨달아야 한다. 이는 단순히 scrollDistance가 실제로 0 값(0)에 도달하지 않기 때문입니다. 따라서 편의를 위해 val < 0의 값에 대해 0으로 변환합니다.

if (val < 0) {
          progressBar.style.width = '0%';
}

전체 코드는 다음과 같습니다.

const progressBar = document.querySelector('.progressBar');
const section = document.querySelector('section');

const scrollProgressBar = () => {
      let scrollDistance = -(section.getBoundingClientRect().top);
      let progressPercentage =
                  (scrollDistance /
                               (section.getBoundingClientRect().height - 
                                                document.documentElement.clientHeight)) * 100;

      let val = Math.floor(progressPercentage);
      progressBar.style.width = val + '%';

      if (val < 0) {
                progressBar.style.width = '0%';
      }
};

window.addEventListener('scroll', scrollProgressBar);

이제 모든 단계가 올바르게 수행되면 웹 사이트를 스크롤할 때 화면 크기에 상관없이 자신만의 진행률 표시줄 애니메이션을 볼 수 있습니다. 즉, 이 애니메이션은 완벽하게 응답합니다.

 

댓글