12/09/2018

부드럽게 이동하는 스크롤 기능(바닐라 JS)

스크롤 이동 기능은 제이쿼리를 이용해서 구현했었는데 이번에는 자바스크립트, 즉 바닐라 JS만을 이용해 구현해보겠습니다.

먼저 에디터로 간단한 구조의 HTML파일을 생성합니다.

<!doctype html>
<html>
<head>
    <title>바닐라 js 부드러운 스크롤</title>
   
    <style>
        #container { height:200000px; position:relative; }
        .btnArea { position:fixed; top:10px; left:10px; }
    </style>   
</head>
<body>
<div id="container">
    <div class="btnArea">
        <button type="button" id="upBtn">위로</button>
        <button type="button" id="downBtn">아래로</button>
    </div>
</div>
</body>
</html>

200,000픽셀의 높이, 항상 상단에 고정된 버튼을 가진 HTML문서가 완성되었습니다.

</body> 바로 위에 스크립트를 추가합니다.

<script type="text/javascript">
    document.getElementById("upBtn").addEventListener('click', function(){
        alert("위로 버튼을 클릭했습니다.");
    });
   
    document.getElementById("downBtn").addEventListener('click', function () {
        alert("아래로 버튼을 클릭했습니다.");
    });
</script>

가장 먼저 버튼 클릭 이벤트가 제대로 작동하는지 확인합니다.

버튼 이벤트가 정상적으로 작동되는걸 확인했습니다.

이제 스크롤을 이동시키는 코드를 추가합니다.

<script type="text/javascript">
    document.getElementById("upBtn").addEventListener('click', function(){
        //alert("위로 버튼을 클릭했습니다.");
        var body = document.getElementsByTagName("body")[0];
        window.scroll({
            behavior: 'smooth',
            left: 0,
            top:body.offsetTop
        });
    });
   
    document.getElementById("downBtn").addEventListener('click', function () {
        //alert("아래로 버튼을 클릭했습니다.");
        var body = document.getElementsByTagName("body")[0];
        window.scroll({
            behavior: 'smooth',
            left: 0,
            top:body.offsetHeight
        });
    });
</script>

변수 body에 태그 <body>를 저장하고, window.scroll() 을 이용하여 스크롤을 이동시킵니다. 그냥 휙휙 움직이는게 아니라, behavior: 'smooth' 로 되어있어서 말그대로 '부드럽게' 움직입니다.

offsetTop은 최상단(정확히는 태그가 시작하는 지점)을 가르키고 offsetHeight는 외부여백을 제외한 높이값입니다.

아래로 버튼을 클릭하면, 부드럽게 스크롤이 최하단으로 이동됩니다.

여기서 끝내도 되겠지만, 위/아래 버튼의 코드가 엄청 비슷하다는것을 알 수 있습니다. 실제로 offsetTop과 offsetHeight만 차이나지요.

중복되는 코드는 최소하시키는게 좋기 때문에, 이 기능은 함수로 만들어 보겠습니다.

헤드 <head> 내부에 스크립트를 추가합니다.

<script type="text/javascript">
    function scrollTo(element, dir) {

        if(dir == "up") {
            dir = element.offsetTop;
        } else {
            dir = element.offsetHeight;
        }

        window.scroll({
            behavior: 'smooth',
            left: 0,
            top: dir
        });
    }   
</script>

scrollTo라는 매개변수 두개를 가진 함수를 만들었습니다. 매개변수 dir에 어느값이 오냐에 따라 offsetTop 또는 offsetHeight값이 저장됩니다.

이제 버튼을 클릭하면, 위에서 작성한 함수가 실행되도록하면 됩니다.

<script type="text/javascript">
    document.getElementById("upBtn").addEventListener('click', function(){
        //alert("위로 버튼을 클릭했습니다.");
        scrollTo(document.getElementsByTagName("body")[0], "up");
    });
   
    document.getElementById("downBtn").addEventListener('click', function () {
        //alert("아래로 버튼을 클릭했습니다.");       
        scrollTo(document.getElementsByTagName("body")[0], "down");
    });
</script>

scrollTo 함수를 호출하고, 매개변수 두가지를 전달합니다.

실행결과는 변함없이 똑같지만, 실제 코드가 줄어들었습니다.

게시물 수정
  1. offsetTop 말고 특정 좌표로 이동하는 것도 가능한가요~?!

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      말씀하신대로 특정 좌표를 넣으면 해당 좌표로 이동할 수 있습니다.

      삭제
  2. 잘 봤습니다
    많이 배웠어요

    답글삭제