🤔 페이지 위로 가기 / 아래로 가기 버튼, 뭔가 부족해
저번에 만든 페이지 이동 버튼을 클릭하면 위아래로 순간 이동하는 건 편리했다.
그런데 양끝단으로 이동이 필요하지 않을 때는 또 어쩔 수 없이 무한 스크롤 지옥이더라.
스크롤 버튼을 누르지 않을 땐 위아래로 조금씩 움직이는 기능을 넣으면 어떨까 하는 생각이 들었다.
💡추가 정보 : 자동 스크롤은 필요없고 버튼 클릭 시 위/아래 이동 기능만 필요한 경우 아래 링크에서 확인하면 된다.
[Info🔍/HTML&CSS] - [Portfolio 스킨] 05. 티스토리 스킨에 스크롤 이동 버튼 구현 방법: 위로 가기, 아래로 가기
✨ 페이지 이동 버튼에 기능 추가하기: 구현 목표 3가지
첫 번째, 버튼을 클릭하면 → 위 또는 아래로 이동
두 번째, 마우스를 버튼 위에 올리면 → 천천히 위 또는 아래로 자동 스크롤
세 번째, 마우스를 떼면 → 자동 스크롤 중지
🔧 포트폴리오 스킨 수정하기
✔ 티스토리 스킨을 편집하기 위해선 꾸미기 → 스킨 변경 → 변경 → 스킨 편집 → HTML 편집 → CSS 또는 HTML 화면으로 들어가면 된다.
코드 수정이 끝났다면 적용을 누른다.
📌 페이지 위로 가기 / 아래로 가기 버튼에 스크롤 기능 추가하기
기존에 만들어둔 JavaScript에 새 기능을 위한 코드를 추가할 거다.
📝 코드 설명
👉 JavaScript
(1) 자동 스크롤을 실행할 변수 만들기
let scrollInterval;
마우스를 버튼 위에 올리면 setInterval()을 실행해서 자동으로 스크롤을 움직이게 하는 게 목표.
setInterval() → 어떤 동작을 반복적으로 실행할 때 사용하는 함수. 멈추려면 clearInterval()을 사용해야 함.
clearInterval()을 사용하려면 setInterval()을 저장할 변수가 필요하다.
∴ scrollInterval 이라는 변수를 미리 선언한 것.
(2) 마우스를 버튼 위에 올렸을 때 자동 스크롤 시작
$("#btn_scroll").mouseenter(function() {
.mouseenter(function() → 버튼에 마우스를 올렸을 때(mouseenter 이벤트 발생) 실행할 코드 작성
(3) 버튼의 방향(위로 가기 / 아래로 가기) 가져오기
let direction = $(this).data("direction");
$(this) → 현재 이벤트가 발생한 요소. 여기서는 #btn_scroll
✔ .data("direction") → 버튼이 위로 가는지, 아래로 가는지 정보를 가져온다.
(4) 스크롤 속도와 실행 간격 설정
let scrollSpeed = 10;
let scrollIntervalTime = 30;
스크롤이 0.03초마다 10px씩 움직여서 이동한다.
✔ scrollSpeed = 10; → 한 번에 이동할 픽셀 수
✔ scrollIntervalTime = 30; → 몇 밀리초(ms)마다 실행할지 설정
(5) 자동 스크롤 실행
scrollInterval = setInterval(function() {
30ms마다 코드가 실행되면서 스크롤이 자동으로 움직인다.
✔ setInterval(function() {...}, 30) → 30ms마다 {} 안의 코드를 실행하는 함수
✔ scrollInterval = setInterval(...) → setInterval()을 실행한 후 변수 scrollInterval에 저장
(6) 현재 스크롤 위치와 화면 크기 정보 가져오기
let currentScroll = $(window).scrollTop();
let windowHeight = $(window).height();
let docHeight = $(document).height();
스크롤이 위나 아래 끝까지 갔는지 확인할 수 있다.
✔ $(window).scrollTop() → 현재 스크롤 위치
✔ $(window).height() → 브라우저 창의 높이
✔ $(document).height() → 문서 전체의 높이
(7) 버튼이 아래로 이동하는 경우
if (direction === "down") {
if (currentScroll + windowHeight < docHeight) {
$(window).scrollTop(currentScroll + scrollSpeed);
} else {
clearInterval(scrollInterval);
}
}
if (direction === "down") → 버튼이 아래로 가기인 경우
✔ if (currentScroll + windowHeight < docHeight) → 아직 아래로 갈 공간이 있다면?
✔ $(window).scrollTop(currentScroll + scrollSpeed) → 현재 위치에서 10px 아래로 이동
✔ else { clearInterval(scrollInterval) → 아래로 갈 공간이 없다면, 즉 맨 아래에 도달하면 자동 스크롤 멈추기
(8) 버튼이 위로 이동하는 경우
else {
if (currentScroll > 0) {
$(window).scrollTop(currentScroll - scrollSpeed);
} else {
clearInterval(scrollInterval);
}
}
else { → 버튼이 위로 가기인 경우
✔ if (currentScroll > 0) → 아직 위로 갈 공간이있다면?
✔ $(window).scrollTop(currentScroll - scrollSpeed) → 현재 위치에서 10px 위로 이동
✔ else { clearInterval(scrollInterval) → 위로 갈 공간이 없다면, 즉 맨 위에 도달하면 자동 스크롤 멈추기
(9) 마우스를 떼면 자동 스크롤 멈추기
$("#btn_scroll").mouseleave(function() {
clearInterval(scrollInterval);
});
마우스를 버튼에서 떼면 clearInterval(scrollInterval);을 실행한다.
✔ $("#btn_scroll").mouseleave(function() { → 버튼에서 마우스를 떼면(mouseleave) 실행
✔ clearInterval(scrollInterval) → ;setInterval()을 멈춰서 자동 스크롤 정지
💻 적용 코드
👉 HTML의 </body> 위에 아래 코드를 입력한다.
<div id="btn_scroll" title="이동">
<img src="./images/btn_top.svg" width="30" height="30" alt="scroll" />
</div>
<script>
$(document).ready(function() {
$("#btn_scroll").hide();
let lastScrollTop = $(window).scrollTop();
let scrollInterval;
$(window).scroll(function() {
let scrollTop = $(window).scrollTop();
let windowHeight = $(window).height();
let docHeight = $(document).height();
if (scrollTop > lastScrollTop) {
$("#btn_scroll img").css("transform", "rotate(180deg)");
$("#btn_scroll").data("direction", "down");
} else {
$("#btn_scroll img").css("transform", "rotate(0deg)");
$("#btn_scroll").data("direction", "up");
}
lastScrollTop = scrollTop;
if (scrollTop === 0 || scrollTop + windowHeight >= docHeight) {
$("#btn_scroll").fadeOut();
} else {
$("#btn_scroll").fadeIn();
}
});
$("#btn_scroll").click(function() {
let direction = $("#btn_scroll").data("direction");
let docHeight = $(document).height();
if (direction === "down") {
$("html, body").animate({ scrollTop: docHeight }, 800);
} else {
$("html, body").animate({ scrollTop: 0 }, 800);
}
});
$("#btn_scroll").mouseenter(function() {
let direction = $(this).data("direction");
let scrollSpeed = 10;
let scrollIntervalTime = 30;
scrollInterval = setInterval(function() {
let currentScroll = $(window).scrollTop();
let windowHeight = $(window).height();
let docHeight = $(document).height();
if (direction === "down") {
if (currentScroll + windowHeight < docHeight) {
$(window).scrollTop(currentScroll + scrollSpeed);
} else {
clearInterval(scrollInterval);
}
} else {
if (currentScroll > 0) {
$(window).scrollTop(currentScroll - scrollSpeed);
} else {
clearInterval(scrollInterval);
}
}
}, scrollIntervalTime);
});
$("#btn_scroll").mouseleave(function() {
clearInterval(scrollInterval);
});
});
</script>
👀 적용 모습
자동 스크롤이 잘 적용됐다♡
모바일에서도 버튼을 꾹 누르고 있으면 자동 스크롤이 작동한다.
꾹 누를 때 이미지 정보창이 나타나는 문제가 있지만🙄
모바일이든 PC든 자동 스크롤이 작동될 때에도 별도의 스크롤이 허용되니까 여러모로 활용도가 높을 것 같다. 만족♡
📍 참고(읽기 편한 스크롤 속도)
scrollSpeed가 너무 크면 한 번에 많이 이동해서 글자가 갑자기 훅 지나간다.
scrollIntervalTime이 너무 짧으면 자주 스크롤되면서 떨리는 느낌이 난다.
scrollIntervalTime이 너무 길면 끊기는 느낌이 들어서 부자연스럽다.
이 두 값을 바꿔보면서 속도를 조절하면 떨림 없이 부드럽게 이동하는 자동 스크롤을 만들 수 있다.
✅ 추천값
📖 글을 읽기 좋은 부드러운 스크롤 : scrollSpeed = 2, scrollIntervalTime = 20
🚀 약간 빠른 자연스러운 스크롤 : scrollSpeed = 3, scrollIntervalTime = 20
🍃 거의 손으로 스크롤하는 느낌 : scrollSpeed = 1, scrollIntervalTime = 20
🔄 조금씩 멈추며 내려가는 느낌 : scrollSpeed = 2, scrollIntervalTime = 30