[Jquery] 특정 엘리먼트로 부드럽게 스크롤 이동하기

일반적으로 특정 타겟으로 스크롤을 이동시키기 위해서는 a태그href 속성#타겟의_ID 를 써주었다. 이렇게 간단하게 클릭 시 해당 타겟으로 스크롤을 이동되게 할 수는 있으나, 밋밋하다. 당장 L0GIC.me의 상단 고정메뉴의 버튼을 누르면 해당 섹션으로 부드럽게 스크롤이 되는 모습을 확인할 수 있다. 과연 어떻게 구현하는 것 일까?

animate()

Jquery 객체는 animate() 라는 메소드를 가지고 있다. animate 함수를 사용하면 해당 객체의 특정 CSS Property 의 값을 부드럽게 변화시킬 수 있다. 변화 양상은 easing 옵션을 통해 변경할 수 있다. 이때, 특정 CSS 프로퍼티는 숫자로 표현가능 해야하며, Color 등의 숫자로 표현할 수 없는 속성의 animate 는 직접 구현해야한다. animate 메소드는 다음과 같이 표현할 수 있다.

$(Element).animate({
	CSS-Property: Value
}, Duration(ms));

우리는 $(“body”) 객체의 animate 메소드를 이용하여, 스크롤 애니메이팅을 해보도록 할 것이다.  이때 사용되는 Property 는 scrollTop 이다. scrollTop 은 스크롤바 최상단 부분의 Y축 좌표를 px로 나타낸 값이다.

여기서 scrollTop은 CSS Property 가 아닌데, 어째서 사용할 수 있는지 의문이 생기는 사람이 있을텐데, Jquery API 문서를 확인해보면, 몇가지 CSS Property가 아닌 값 scrollTop 혹은 scrollLeft 와 같은 애니메이션 적용이 가능한 값들은 사용할 수 있다고 적혀있다. (In addition to style properties, some non-style properties such as scrollTop and scrollLeft, as well as custom properties, can be animated.)

특정 좌표로 부드럽게 스크롤하기

특정 타겟으로 스크롤 시키기 전에 특정 좌표로 부드럽게 이동시키는 소스코드를 작성해보자.

$("body").animate({
	scrollTop: 300
}, 500);

//300px로 부드럽게 스크롤한다.

위와같이 3줄정도의 소스코드로 간단하게 구현이 가능하다.

특정 엘리먼트로 부드럽게 스크롤하기

특정 엘리먼트로 향하는 부드러운 스크롤의 구현도 간단하다. 해당 엘리먼트의 Y축 좌표를 구해와서 그대로 적용시키면 된다. 특정 엘리먼트의 Y축 좌표는 Jquery 객체의 offset() 메소드를 사용하여, top 프로퍼티를 가져오면 된다.

var scrollPosition = $("#ID").offset().top;

이런식으로 특정 엘리먼트의 Y좌표를 가져 올 수 있는데, 바로 아래와 같이 응용하면 된다.

var scrollPosition = $("#ID").offset().top;

$("body").animate({
	scrollTop: scrollPosition
}, 500);

간단하게 구현할 수 있다. 여기서 한단계 더 응용해보면, 재밌는 것을 만들어 볼 수도 있다. 클릭하면 원하는 엘리먼트로 스크롤되는 메뉴를 만들어 보도록하자.

클릭시 타겟으로 스크롤되는 메뉴 만들기

이 글에서는 HTML5 에서 제공되는 Data-* Attribute 를 활용하여, 스크롤 메뉴를 제작해보도록 하겠다.

<ul class="menu">
  <li data-target="#about"> 소개 </li>
  <li data-target="#member"> 멤버 </li>
  <li data-target="#contact"> 연락 </li>
</ul>

위와 같이 간단하게 메뉴를 구성해주자. ul태그나 li태그 같은것이 중요한 것이 아니라, 메뉴로 사용할 요소에 data-* 속성을 사용한 것에 주목하자. 우리는 저 소스코드에서 li태그를 클릭하면 해당하는 요소로 스크롤이 되게끔 구현해보겠다. data-target 속성에는 스크롤될 타겟의 선택자를 써 넣는다.

$(".menu li").click(function() {

}

일단 위과 같이 메뉴에 클릭 이벤트를 바인딩한다. 그리고 2번째에서 구현한 특정 개체로의 스크롤 소스코드를 조금 수정해보자.

$(".menu li").click(function() {
  var scrollPosition = $($(this).attr("data-target")).offset().top;

  $("body").animate({
        scrollTop: scrollPosition
  }, 500);
}

Jquery 객체의 attr 메소드는 인자로 속성명을 넣어주면, 그 속성의 값을 반환해준다. 그것을 이용하여 this 키워드를 사용하여 이벤트를 발생시킨 객체의 data-target 속성을 가져왔고, 그 속성에는 우리가 특정 엘리먼트의 선택자를 써 넣어주었다. 그 선택자를 이용해 특정 엘리먼트의 Y좌표를 구할 수 있었고, 그 좌표값을 이용해 스크롤을 할 수 있는 것이다.

설명을 조금 어렵게 써 놓았을 뿐이지 굉장히 간단한 원리로 작동한다.