스크롤을 내리며 원하는 항목에 지날때 해당되는 탭 요소가 액티브 되어 보여주는 효과를 구현하게 되었고 구현 방법을 소개하고자 한다
Div
태그에 동일한 className
을 지정스크롤 이벤트
를 추가하여 해당 Section 의 className
이 몇번째에 나온 것인지 판단하여 인덱스 값을 판단다섯개의 Div
를 임의로 생성하고 동일한 className scroll-tab
을 지정
사용자는 스크롤을 돌리게 되면 스크롤 이벤트가 발생하고 handleScroll
함수가 동작하게 된다.
handleScroll
함수의 동작은 다음과 같다.
3-1) export const handleScroll = (setValue: Function) => (event: Event) => { ... }
handleScroll 함수는 함수를 반환하는 함수입니다. 이는 함수 커링(function currying) 기법을 사용하는 것이며, setValue라는 함수를 인자로 받습니다 이렇게 하면 setValue 함수를 내부 함수에서 사용할 수 있게 됩니다.
3-2) const divElements = document.querySelectorAll('.scroll-tab')
document.querySelectorAll('.scroll-tab')을 사용하여 CSS 클래스 이름이 "scroll-tab"인 모든 요소를 선택합니다. 이 요소들은 페이지의 각 섹션을 나타냅니다.
3-3) const scrollY = window.scrollY
window.scrollY를 사용하여 현재 페이지의 수직 스크롤 위치를 가져옵니다. 이 값은 페이지의 맨 위에서부터 스크롤한 거리를 나타냅니다.
3-4) for (let i = 0; i < divElements.length; i++) { ... }
선택된 .scroll-tab 요소들을 반복하여 각 섹션의 위치 정보를 확인합니다.
3-5) const { top, bottom } = divElement.getBoundingClientRect()
getBoundingClientRect() 메서드를 사용하여 현재 반복 중인 섹션의 상단(top)과 하단(bottom)의 위치 정보를 가져옵니다. 이 정보는 현재 화면에 보이는 섹션의 위치를 나타냅니다.
3-6) if (top <= window.innerHeight / 2 && bottom >= window.innerHeight / 2) { ... }
현재 섹션의 상단이 화면 중앙 이하에 있고, 하단이 화면 중앙 이상에 있을 때, 해당 섹션은 화면 중앙에 표시되는 것으로 간주합니다. 이러한 조건을 만족하면 해당 섹션을 활성 상태로 처리합니다.
3-7) setValue(i)
활성 섹션의 인덱스 i를 setValue 함수를 통해 설정합니다. 이렇게 하면 현재 화면 중앙에 있는 섹션의 인덱스가 저장되어, 컴포넌트 내에서 이를 사용하여 활성 탭을 표시하거나 다른 작업을 수행할 수 있습니다.
AcriveTab
은 현재 몇번째 Scroll-tab
을 지나고 있는지 상태 값을 저장하게 되고 사용자는 해당 Tab
에서 조건부 랜더링을 통해서 Active
g한 효과를 구현 할 수 있다.const Components = () => {
const [activeTab, setActiveTab] = useState<number>(0);
useEffect(() => {
const scrollEventListener = handleScroll(setActiveTab);
window.addEventListener('scroll', scrollEventListener);
return () => {
window.removeEventListener('scroll', scrollEventListener);
};
}, []);
return (
<>
<div className="scroll-tab">첫번째 섹션</div>
<div className="scroll-tab">두번째 섹션</div>
<div className="scroll-tab">세번째 섹션</div>
<div className="scroll-tab">네번째 섹션</div>
<div className="scroll-tab">다섯번째 섹션</div>
</>
);
};
export default Components;
export const handleScroll = (setValue: Function) => (event: Event) => {
const divElements = document.querySelectorAll('.scroll-tab');
// 현재 스크롤 위치를 가져옵니다.
const scrollY = window.scrollY;
// 각 div 요소의 위치 정보를 확인하고, 현재 스크롤 위치에 따라 활성 div를 결정합니다.
for (let i = 0; i < divElements.length; i++) {
const divElement = divElements[i];
const { top, bottom } = divElement.getBoundingClientRect();
// 예를 들어, 상단과 하단이 화면 중앙 이내에 있을 때 해당 div를 활성으로 표시합니다.
if (top <= window.innerHeight / 2 && bottom >= window.innerHeight / 2) {
setValue(i); // 활성 div의 인덱스를 상태에 저장합니다.
break;
}
}
};
이렇게 구현 하는 방법보다 더 효율적인 방법이 있을 수 있으며 틀린 부분이 있을 수 있어, 더 좋은 방법이나 수정해야할 부분이 있다면 댓글로 남겨주세요!