요즈음 사이트에서 많이 볼 수 있는 스크롤(wheel)시에
섹션별로 페이지가 넘어가도록 하는 기능을 정리해보려고 합니다.
지금은 그냥 영역을 나누기만 해서 간단하지만 나중에 포트폴리오를 작성할 때는
<div>
태그 안에다가 원하는 내용을 작성! (css는 생략)
<body>
<div class="content"><h1>1</h1></div>
<div class="content"><h1>2</h1></div>
<div class="content"><h1>3</h1></div>
<div class="content"><h1>4</h1></div>
<div class="content"><h1>5</h1></div>
<div class="content"><h1>6</h1></div>
<div class="content"><h1>7</h1></div>
</body>
window.addEventListener("wheel", function(e){
e.preventDefault();
},{passive : false});
우리가 사용할 이벤트는 wheel이벤트인데, 휠을 굴렸을 때 스크롤이 되지 않도록 하려면 wheel의 기본 이벤트인 scroll를 제거를 해줘야 한다.
근데 여기서 패시브모드
를 해제를 해야 한다고 한다.
passive
는 addeventListener()
옵션 중에 1개이다
passive옵션은 true와 flase 값을 가지게 된다
flase인 경우
preventDefault()를 이용해서 이벤트 자체를 막을 수 있기 때문에,
브라우저는 scroll를 계속할지 안할지를 매번 검사하게 된다.
passive 옵션의 기본값이다.
true인 경우
스크롤이벤트를 막지 않겠다!
preventDefalt()를 사용할 수 없다.
passive모드의 기본값이 flase이니까따로 써줄 필요가 없지 않나?
기본이벤트를 제거를 해도 여전히 스크롤이 여전히 되고 오류가 발생이된다고 한다.
이유는 패시브모드에서 동작하는 이벤트 이기 때문에그래서 패시브 모드를 끈 상태에서 기본이벤트를 제거를해야 되는거라 한다.
let $html = $("html");
let page = 1; // 뷰포트에 표시되는 페이지의 번호
let lastPage = $(".content").length; // 마지막 페이지의 번호
$html.animate({scrollTop:0},10); // 문서(페이지)가 로드되면 첫 페이지 시작
$(window).on("wheel", function(e){ 1️⃣
if($html.is(":animated")) return; 2️⃣
if(e.originalEvent.deltaY > 0){ 3️⃣
if(page== lastPage) return; 4️⃣
page++; 5️⃣
}else if(e.originalEvent.deltaY < 0){ 3️⃣
if(page == 1) return; 6️⃣
page--; 5️⃣
}
var posTop = (page-1) * $(window).height(); 7️⃣
$html.animate({scrollTop : posTop}); 8️⃣
});
이벤트 핸들러로 마우스 휠을 굴리면 발생하는 이벤트
아래에서 호출된 ✨.animate 메서드로 생성된 스크롤 효과가 쌓이지 않도록
스크롤이 진행되는 동안 발생하는 wheel이벤트는 무시한다.즉 현재 페이지가 애니메이션 중인지 확인하고 애니메이션이 진행 중이라면 함수를 종료하고 더 이상의 동작을 수행하지 않도록 한다.
e(jQuery가 반환) .originalEvent(자바스크립트에서의 원래 이벤트) .deltaY(마우스 휠을 어느 방향으로 얼만큼을 굴렸는지 확인하는것, 양수이면 아래쪽으로 굴린 거, 음수이면 위쪽으로 굴린 거다)
마지막 페이지인 경우에는 이벤트 핸들러 종료 (스크롤될 것이 없으니 마지막에서 멈춰!!)
스크롤을 아래로 했으면 페이지 +1, 위로 올렸으면 -1씩 시키기
첫 번째 페이지인 경우에도 이벤트 핸들러 종료(올라갈 곳이 없으니 첫 번째에서 멈춰!!)
계산된 스크롤 위치를 설정합니다. 페이지 번호에 따라 스크롤 위치를 계산
계산된 스크롤 위치로 애니메이션을 사용하여 스크롤 (scrollTop 속성을 이용하여 문서를 특정 위치로 스크롤)
위에서 언급된 :animate 메서드란 무엇인가.
:animated는 jQuery에서 애니메이션 중인 요소를 선택하는 필터입니다.
:animated는 현재 애니메이션 중인 모든 요소를 선택합니다.
이 필터는 주로 :animated를 사용하여 애니메이션 중에 중복 애니메이션을 방지하거나
특정 상황에서만 애니메이션을 실행하는 등의 제어 목적으로 활용됩니다.
작업도중 오류를 발견해서 이것저것 검색을 하다가 fullpage.js라는 라이브러리를 발견 하였다.
fullpage 라이브러리로 가로 스크롤링도 구현할 수 있는것 같다! 조금 더 찾아보자!
- origin: 사용자가 떠나는 섹션에 대한 정보를 담고 있는 객체입니다.
- origin.index: 현재 섹션의 인덱스(0부터 시작)입니다.
- origin.item: 현재 섹션의 요소(HTMLElement)입니다.
- destination: 사용자가 이동하려는 목표 섹션에 대한 정보를 담고 있는 객체입니다.
- destination.index: 이동하려는 목표 섹션의 인덱스(0부터 시작)입니다.
- destination.item: 이동하려는 목표 섹션의 요소(HTMLElement)입니다.
- direction: 이동 방향을 나타내는 문자열입니다. 'up', 'down', 'left', 또는 'right' 중 하나일 수 있습니다.
onLeave //사용자가 현재 섹션을 떠나기 시작할 때.
afterLoad //사용자가 섹션을 완전히 떠났을 때, 새로운 섹션에 도달했을 때.
afterRender //호출 시점: fullPage.js가 초기화되고 페이지가 완전히 로드된 후.
afterResize //호출 시점: 브라우저 창 크기 조정 후.
afterReBuild //호출 시점: fullPage.js가 다시 빌드된 후.
afterResponsive //호출 시점: 반응형 모드가 변경된 후.
afterSlideLoad //호출 시점: 수평 슬라이드 섹션 내에서 슬라이드가 로드된 후.
onSlideLeave //호출 시점: 수평 슬라이드 섹션 내에서 슬라이드를 떠나기 시작할 때.
안녕하세요 위에 알려주신 코드로 적용해보았는데 원하는 만큼 잘 작동되네요 감사합니다!
그런데 마우스 휠로 스크롤할 때는 잘 되는데 트랙패드로 스크롤을 하면 2, 3페이지씩 넘어가더라구요,,
어떤 운영체제를 사용하시는지 모르겠지만 어떻게 해야 1페이지씩 스크롤할 수 있는지 알려주시면 감사하겠습니다ㅜㅜ