2022. 6. 5. 11:31ㆍReact
티스토리 블로그를 자주 쓰신다면 가로로 스크롤 진행률이 표시되는 UI를 많이 보셨을 것입니다.
많은 브라우저에서 세로 스크롤을 잘 안 보이도록 감춰놓는 경우가 많기 때문에 얼마나 읽어야지 콘텐츠가 끝이 나는지 짐작하기가 어렵습니다. 이때 가로 스크롤 진행률 UI를 사용한다면 사용자들도 콘텐츠의 길이를 한 번에 확인할 수 있고, 좋은 색상만 선택한다면 외관상 한층 업그레이드된 느낌을 받을 수 있습니다.
아래 이미지는 필자가 개발하고 있는 웹에 해당 UI가 적용된 모습입니다.
해당 UI는 요구사항은 아니었지만 비교적 긴 매거진 콘텐츠에서 사용자가 얼마나 읽었는지 짐작할 수 있는 UI는 꼭 필요하다고 생각했기 때문에 추가하게 되었습니다. 추후에는 해당 바에 주요 제목들을 링크해두고 바로 이동할 수 있도록 기능을 추가할 예정입니다.
컴포넌트 만들기
본격적으로 컴포넌트를 만들기 위해서 아래와 같이 jsx를 작성해줍시다. 참고로 필자는 모듈 scss를 사용했기 때문에 아래와 같이 작성을 했고 다른 css 방식을 사용하시는 분은 알아서 맞게 변경을 해주시면 됩니다.
components/HorizontalProgress.jsx
import React from "react";
import styles from "styles/components/HorizontalProgress.module.scss";
const HorizontalProgress = ({ scroll }) => {
return (
<div className={styles.container}>
<div className={styles.progress} style={{ width: scroll }}/>
</div>
);
};
export default HorizontalProgress;
styles/components/HorizontalProgress.module.scss
.container {
width: 100%;
background: #ccc;
position: fixed;
width: 100%;
.progress {
height: 8px;
background: blue;
width: 0%;
}
}
hooks/useDetectScroll.js
import { useState, useEffect, useCallback } from "react";
const useDetectScroll = () => {
const [scroll, setScroll] = useState(0);
const handleProgressBar = useCallback(() => {
const totalScroll = document.documentElement.scrollTop;
const windowHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const scroll = `${(totalScroll / windowHeight) * 100}%`;
setScroll(scroll);
}, []);
useEffect(() => {
window.addEventListener("scroll", handleProgressBar);
return () => {
window.removeEventListener("scroll", handleProgressBar);
};
}, [handleProgressBar]);
return { scroll };
};
export default useDetectScroll;
해당 훅을 살펴보면, 스크롤 이벤트가 일어날 때마다 handleProgressBar라는 함수가 실행되도록 이벤트 리스너를 달아주고 있습니다.
스크롤될 때 마다 실행되는 이 handleProgressBar 함수 내부에서는 scrollTop 메서드를 통해 수직 스크롤 위치를 px로 받고 화면 윈도 높이 (scrollHeight - clientHeight)까지 px로 받은 뒤 두 개의 값을 이용해 % 값을 구하고 해당 값을 상태 값으로 지정한 뒤 내보내 주고 있습니다.
요소 사이즈와 스크롤에 대해 좀 더 자세한 설명이 필요하신 분들은 해당 자료를 참고해주시길 바랍니다.
사용하실 때에는 사용하고자 하는 곳에서 해당 훅을 호출한 뒤 반환되는 scroll값만 전에 만든 HorizontalProgress 컴포넌트에 넘겨주기만 하면 됩니다.
const Magazine = () => {
const { scroll } = useDetectScroll();
return (
<HorizontalProgress scroll={scroll} />
//...생략
)
}
'React' 카테고리의 다른 글
[React] 페이지 이동시 애니메이션 효과 적용하기 (feat. framer motion) (0) | 2022.09.24 |
---|---|
[React] 스크롤시 등장/퇴장 애니메이션 효과 적용해보기 (feat. framer motion & react-intersection-observer) (0) | 2022.09.03 |
Quill React 에디터 사용해보기 (이미지 업로드 및 사이즈 조절) (7) | 2022.03.22 |
React 성능 최적화를 위한 useMemo 와 useCallback (0) | 2022.03.09 |
[React] 드롭다운 메뉴 만들기 (feat. useRef, useState) (0) | 2022.02.27 |