스크롤스파이(scrollspy) 구현
SPA(Single Page Application) 웹페이지에서 많이 쓰이는 스크롤스파이를 구현해보자. 가끔 혹자는 스크롤 네비게이션이라고도 부르는 것 같다.
스크롤스파이는 스크롤이 긴 페이지에서 유저가 길을 잃지 않게 도와주는 역할을 한다.
카카오페이 홈페이지에 PC로 들어가면 어떻게 구현되어 있는지 확인할 수 있다.
- 카카오페이 홈페이지
스텝 바이 스텝으로 구현해본다.
아래 단계는 github에 커밋으로 구분되어 있다.
1단계
global 스타일링은 최소한으로 하고, SPA 느낌만 내기 위해 <section>태그 5개를 넣었다. 각 <section>은 색깔로 구분했다.
2단계
navigation dots를 만들기 위한 <ul>과 <li>를 넣는다.
href 속성에 #id가 있는데, 이것만으로도 클릭시 해당 섹션으로 이동한다.
스크롤이 위치한 섹션은 active 클래스가 붙을 예정이므로 첫번째 <section>에 active를 미리 붙였다.
data-scroll 속성은 조금 있다 javascript에서 쓰인다.
3단계
navigation dots의 스타일을 준다. 언제나 발목을 잡는건 CSS다.
- #navbar의 위치가 스크롤시에도 고정되도록 position:fixed 하고 수직센터링 한다.
- <ul>의 list-style-type을 없애고, <li>의 위치를 조정한다.
- <li>에 속한 <a>와 <span>을 적절히 꾸민다(ㅎㅎ;;;;;;;;;;;)
- <span>은 .active가 붙었을 때와 hover 상태일 때 opacity:1 이 되도록 하고 그렇지 않을 땐 숨긴다.
그럼 아래와 같은 결과가 나온다.
모양은 얼추 비슷해졌고, 클릭 시 해당 섹션으로 이동하는 그럴듯한 네비게이션이 되었다.
그러나 아직은 스크롤을 따라가지 않기 때문에 자바스크립트가 필요하다.
4단계
(jQuery 사용)
먼저 dots를 클릭했을 때 onClick 이벤트를 부여한다.
offset().top 을 이용해 각 타겟의 좌표 맨 위로 이동하고, 부드러운 스크롤 효과를 준다.
해당 dot을 클릭시 active 클래스를 부여한다.
앵커 클릭시 url 뒤에 #id가 남는 것을 막기 위해 e.preventDefault()를 사용한다.
부드러운 스크롤링까진 됐는데, active 클래스가 계속 남아있어 클릭하기가 무서운 것이다. 그리고 아직 스크롤을 따라가지도 않는다.
5단계
마지막 단계다.
- 스크롤할 때마다 각 섹션의 꼭대기 좌표와 현재 스크롤 위치를 받고 비교한다.
- 그 차이가 20 이하면 모든 .dot의 active 클래스를 삭제한 뒤
- 처음 .dot에 부여했던 속성인 data-scroll 이 해당 id인 곳을 찾아 active 클래스를 부여한다.
추가
스타일링이 구리긴 한데 아무튼 기능은 완성했다.
그런데 height를 잘못 주는 바람에 스크롤을 맨 아래까지 내려도, 마지막 <section>의 offset().top에 닿질 않아서;;
footer를 추가했다.
DEMO
https://saintsilver.github.io/scrollspy/ 에서 확인해볼 수 있다.
덧붙여
네비게이션이 dots 형태가 아니라 상단의 심플한 메뉴형태인 것도 많고
scrollspy를 section-slider 형태로 합쳐놓은 페이지들도 자주 볼 수 있다.
그런데 사실 ... .. .. . . . .
부트스트랩이 출동하면 어떨까?
위 링크를 참고하면 어이없을 정도로 쉽게 구현할 수 있으니까, 부트스트랩을 사용할 예정이라면 저처럼 하지 마세요.