타겟 요소까지 스크롤이 되는 것은 다음과 같이 정의할 수 있다.
타겟 요소 영역의 최상단이 뷰포트의 상단과 일치하는 것
특정 요소가 있는 좌표로 스크롤이 이동하는 기능을 구현하기 위해선 아래의 것들이 필요하다.
뷰포트 (화면에 웹페이지가 렌더링되는 영역을 말함)와 특정 요소의 상대적인 크기, 위치 정보가 담긴 DOMRect
객체를 반환하는 웹 API 메소드이다.
아래는 콘솔에 getBoundingClientRect
메소드를 호출한 결과이며 (콘솔창 참고) 각 프로퍼티의 의미는 이미지를 참조하면 된다.
프로퍼티 중 top
값이 바로 나에게 필요한 참조값이다.
window
객체의 프로퍼티로써 문서의 최상단으로부터 현재 스크롤까지의 거리를 나타낸다. 읽기 전용 프로퍼티이기 때문에 window.pageYOffset = 300;
을 입력해도 해당 좌표로 스크롤이 되진 않는다.
window.addEventListener('scroll', () => {
console.log(window.pageYOffset);
});
브라우저 콘솔에 위 코드를 입력하면 스크롤이 움직일때마다 window.pageYOffset
값을 출력되는 것을 볼 수 있다.
스크롤이 0일때만 스크롤링 버튼을 누르는 것이 아니기 때문에 요소의 top 값이 변하더라도 현재 스크롤 위치에 맞춰서 위치 값을 보정해줘야 한다.
targetElement.getBoundingClientRect().top + window.pageYOffset
현재 스크롤이 어디에 있던, 언제나 위 값을 참조하여 스크롤 하면 된다.
이제 원하는 좌표로 스크롤을 이동시켜주는 기능만 찾으면 된다.
문서의 특정 좌표로 스크롤 이동하는 window
의 메소드이다.
window.scrollTo(x좌표, y좌표)
window.scrollTo(옵션)
// example
window.scrollTo(0, 1000);
window.scrollTo({
top: 1000,
left: 0,
behavior: "smooth"
});
scrollIntoView
는 앞선 방법보다 최신 버전의 기술이라고 할 수 있다.
타겟 요소의 부모 요소까지 스크롤을 내려준다.
element.scrollIntoView();
element.scrollIntoView(alignToTop); // Boolean parameter
element.scrollIntoView(scrollIntoViewOptions); // Object parameter
alignToTop
(Optional)
true
: 타겟의 최상단이 뷰포트의 상단에 닿는다 scrollIntoViewOptions: {block: "start", inline: "nearest"};
false
: 타겟의 최하단이 뷰포트의 상단에 닿는다 scrollIntoViewOptions: {block: "end", inline: "nearest"}
scrollIntoViewOptions
(Optional)
트랜지션 애니메이션과 세로 정렬, 가로 정렬 정보를 담은 객체 인자를 전달한다
behavior
: 스크롤링 동작이 부드럽게 이어지는지 여부auto
(default), smooth
start
(default), center
, end
, nearest
start
(default), center
, end
, nearest
var element = document.getElementById("box");
element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({block: "end"});
element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
currentSection.scrollIntoView({behavior: 'smooth'});
scrollTo
보다 훨씬 간편하게 단 한줄로 기능이 구현된다.
호환성을 살펴봐도 그렇게 큰 차이는 없어보이고 사실 호환성에 대해 아직 잘 모른다.
다만 코드펜을 Embed해서 포스팅에 넣었는데, 스크롤 버튼을 누르는 순간 아이프레임 뿐만 아니라 블로그를 보고있는 뷰포트도 움직이는 현상이 발생한다.
아직은 왜 그런지 알 수 없다...
특정한 타겟 요소로 스크롤을 할 수 있는 scrollIntoView
가 더 간결하고 편한 것 같다. 만약 특정한 좌표값으로 이동하는 문제라면 scrollTo
도 나쁘지 않은 선택이 될 것 같다.
[1] Window.scrollTo()
[2] Element.scrollIntoView()