📢 어렵고 정석적인 개념 설명보다는 저같은 초보자도 이해하기 쉽게 정리하는 것을 원칙으로 포스팅하고 있습니다. 😄
개념
가끔 웹 사이트를 돌아다니다보면, 스크롤을 할 때마다 한 섹션씩 휙-휙 넘어가는 웹을 경험한 적이 있을 것이다.
마치 PPT처럼 여러 번 스크롤을 해도 한 섹션씩 넘어가는 이벤트는 어떻게 만들어야 할까?
원리는 먼저 스크롤을 통제한 채 스크롤의 움직임을 인지하고, 그 움직임의 값에 따라 window의 scrollTop 값을 바꿔주기만 하면 된다. 나 같은 경우 페이지(섹션)마다 변수값으로 하나의 페이지 번호를 달아주고, 그 페이지 번호에 따라서 스크롤을 통제하는 식의 이벤트를 사용했다.
해결
let pageNumber = 0; // 섹션 넘버 지정
먼저, 초깃값(가장 처음에 나오는 섹션의 번호)은 0으로 주었다. 그리고 총 5페이지의 섹션이 있다고 가정하겠다.
그럼 pageNumber는 0부터 4까지 있다고 생각하면 된다.
$(window).on("wheel", function(e){
if ($('html').is(":animated")) return; // 스크롤 중에는 함수 작동을 멈춤
if (e.originalEvent.deltaY > 0){
if (pageNumber >= 4) return; // 4 이상일 경우 'pageNumber++'를 멈춤
pageNumber++;
} else if (e.originalEvent.deltaY < 0){
if (pageNumber <= 0) return; // 0 이하일 경우 'pageNumber--'를 멈춤
pageNumber--;
}
$('html').stop().animate({
scrollTop: window.innerHeight * pageNumber // 해당 섹션의 Top 위치로 이동
})
}
if ($('html').is(":animated")) return;
이게 없으면 우리는 스크롤을 위 아래로 한 번 할 때마다 가장 끝 값인 4 혹은 0으로만 이동하게 된다.
즉, 스크롤 시에는 이벤트를 멈출 수 있는 브레이크 장치가 필요한 것이다.
코드를 직역하자면 "html 문서가 animated 상태라면, return; 하겠다"가 된다. (=함수를 중단하고 빠져나가겠다)
if (e.originalEvent.deltaY > 0)
originalEvent는 순수 DOM 이벤트 객체를 말하며, originalEvent 속성을 이용하여 원래의 DOM 이벤트 객체에 접근할 수 있다. deltaY는 마우스 휠을 했을 때의 값인데 아래로 휠을 내리면 양수, 위로 휠을 올리면 음수 값을 반환한다. 밑으로 내릴 때마다 페이지 번호가 올라가듯이 deltaY도 양수 값을 반환한다고 이해하면 쉽다. deltaY 대신 wheelDelta 속성을 사용해도 좋다.
if (pageNumber >= 4 || pageNumber <= 0) return;
1번에서 스크롤을 하는 도중에 변수 pageNumber의 증감을 막았다면, 스크롤 시 정해진 페이지를 벗어났을 때도 함수의 작동을 멈추게 하는 브레이크 장치가 필요하다. 페이지(섹션)의 수는 5개인데, 5개를 넘어가도 계속 pageNumber의 값이 증가한다면 페이지를 위로 올릴 때 바로 작동되지 않을 수가 있기 때문이다.
페이지(섹션)이 총 5개라고 가정했기 때문에, 4 이상 혹은 0 이하일 경우 함수의 작동을 멈추게 했다. (클린 코드를 위해 숫자가 아닌 섹션의 length 값을 넣어도 된다.)
animate({scrollTop: window.innerHeight * pageNumber})
사용자의 화면 높이인 innerHeight 값에 pageNumber 값을 곱해 scrollTop을 구했고, 스크롤 할 때마다 해당 scrollTop 위치로 이동하게 하였다.
'JavaScript' 카테고리의 다른 글
[JavaScript] 알아두면 유용한 배열 메서드 (map(), forEach() 등) (0) | 2022.04.14 |
---|---|
[JavaScript] 스크롤 제어하기 및 스크롤 숨기는 방법 (0) | 2022.04.07 |
[JavaScript] ES6 화살표 함수 (Arrow Function) (0) | 2022.03.16 |
[JavaScript] 특정 요소가 화면 끝에 닿으면 이벤트 발생시키기 (0) | 2022.03.07 |
[JavaScript] 시간 지연 함수 setTimeout() / setInterval() (0) | 2022.01.26 |