본문 바로가기

[Portfolio 스킨] 24. 부드러운 자동 스크롤 구현 방법: 마우스 올리면 천천히 이동하는 기능

728x90

코딩 알못 별이의 티스토리 스킨 꾸미기 도전 썸네일

 

🤔 페이지 위로 가기 / 아래로 가기 버튼, 뭔가 부족해

 

저번에 만든 페이지 이동 버튼을 클릭하면 위아래로 순간 이동하는 건 편리했다.

그런데 양끝단으로 이동이 필요하지 않을 때는 또 어쩔 수 없이 무한 스크롤 지옥이더라.

스크롤 버튼을 누르지 않을 땐 위아래로 조금씩 움직이는 기능을 넣으면 어떨까 하는 생각이 들었다.

 

💡추가 정보 : 자동 스크롤은 필요없고 버튼 클릭 시 위/아래 이동 기능만 필요한 경우 아래 링크에서 확인하면 된다.

[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

 

 

 

728x90