* javascript.info 자료를 번역 및 일부 첨삭한 내용이다.
이번 포스팅에서는 다음 두 가지를 구하는 방법에 대해 알아보자.
( width와 height의 원리는 동일하므로 예제의 적합성에 따라 window에서는 width를 document에서는 height을 기준으로 작성하겠다. )
이를 위해, <html>
태그에 해당하는 루트 document 요소의 document.documentElement
를 사용할 것이다. ( 사용에 예외가 있으나, 밑에서 언급하겠다. )
document.documentElement
는 읽기 전용 속성으로 문서의 루트 요소를 나타내는 Element를 반환한다. HTML 문서를 예로 들면<html>
요소를 반환한다.
: window의 width는document.documentElement
의clientWidth
을 사용하면 된다. 참고로 clientWidth는 스크롤 바를 포함하지 X
// 예시
alert(document.documentElement.clientWidth);
window.innerWidth
!대부분의 경우, 우리는 무언가를 그리거나 배치하기 위해서 '사용 가능한' (스크롤바를 제외한) window의 너비 및 높이를 필요로 한다.
alert( window.innerWidth ); // full window width
alert( document.documentElement.clientWidth ); // window width - scrollbar
clientWidth
는 스크롤바 제외한 너비를 제공한다. 즉, (content가 이용할 수 있는) 문서의 보여지는 부분의 너비를 반환한다.
그러나, window.innerWidth
은 스크롤바를 포함한 값을 반환하므로 사용에 적절하지 않다.
❗ Note
최상위 기하학적 프로퍼티들은 HTML안에<!DOCTYPE HTML>
이 없으면 조금 다르게 작동할 수도 있다. 따라서, 항상 DOCTYPE을 꼭 써야 한다.
이론상, 루트 document 요소가 document.documentElement
이고 이것이 모든 content들을 둘러싸고 있기 때문에, document.documentElement.scrollHeight
으로 document의 전체 높이를 측정할 수 있다.
하지만 크롬, 사파리, 오페라에서는 스크롤이 없을 경우(여기선 수직 스크롤) 의도대로 작동하지 않는다.
이 경우, documentElement.scrollHeight
은 documentElement.clientHeight
보다 작을 수 있다.
따라서 전체 문서 높이를 안정적으로 확보하려면, 다음 속성들의 최대치를 가져오면 된다.
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
// ❗ 사파리에서는 document.documentElement대신에 document.body를 써야 한다.
alert(`Full document height, with scrolled out part: ${scrollHeight}`);
X축 스크롤 정보를 얻고 싶을 땐
scrollLeft
를 사용하면 되지만, 여기선 Y축 기준으로 살펴 보겠다.
DOM 요소들은 element.scrollTop
속성으로, document는document.documentElement.scrollTop
으로 대부분의 브라우저에서 현재 수직으로 얼만큼 스크롤 되어 있는지 그 픽셀 수를 알 수 있다.
그러나 사파리에서는 document.documentElement
대신에 document.body
를 써줘야 한다는 예외성이 존재한다.
다행히도 이러한 특성에 대해 전혀 기억할 필요가 없이 pageYOffset
을 사용하면 된다.
문서가 수직으로 얼마나 스크롤 됐는지 픽셀 단위로 반환한다.
alert(`Current scroll from the top: ${window.pageYOffset}`);
❗
pageYOffset
은scrollY
의 다른 이름으로, 일부 오래된 브라우저는scrollY
대신pageYOffset
만 지원하는 경우가 있지만 노후 환경을 신경쓰지 않아도 된다면 둘 중 아무거나 사용해도 괜찮다.
요소나 문서 모두 scrollTop
를 변경함으로써 스크롤링 할 수 있지만,
element.scrollTop = intValue; // Set the number of pixels scrolled.
이 외에도 scrollBy(), scrollTo(), scroll(), scrollIntoView()
와 같은 더 간단하고 범용적인 솔루션이 있으니 살펴보도록 하자.
→ element, window에서 모두 사용 가능
🌟 참고로 scrollBy( ), scrollTo( ), scroll( )는 다음 두 가지 파라미터를 가진다. (예시는 scrollTo 메소드로 통일)
window.scrollTo(0, 1000);
window.scrollTo({
top: 1000,
left: 0,
behavior: 'smooth' // behavior에는 'smooth'와 'auto'가 있다.
});
옵션에는 요소를 스크롤할 위치, 스크롤을 smooth하게 할 건지의 여부를 지정하는 속성이 포함되어 있다.
세 가지 메소드 모두 동일한 옵션 사전을 공유한다.
자바스크립트에서 페이지를 스크롤하려면 DOM이 완전히 작성되어져 있어야 한다. 예를 들어,
<head>
의 스크립트에서 페이지를 스크롤하려고 하면 작동하지 않는다.
'현재 위치'을 기준으로 '상대적'으로 페이지를 스크롤한다.
window.scrollBy(0,100); // 현재 위치에서 페이지를 100px 아래로 스크롤 한다.
scroll( )
과 scrollTo( )
는 지정된 요소 내부의 특정 (절대)좌표로 스크롤 한다. 이는 아래와 같이 scrollTop
으로 설정하는 것과 같다.
const element = document.querySelector("#box");
element.scroll(0,50); // x=0, y=50px인 지점으로 스크롤
element.scrollTo(0,50); // ...
element.scrollTop=50; // 모두 같은 결과를 가짐
scrollIntoView( )
를 호출한 요소가 사용자에게 보이도록 요소의 상위 컨테이너를 스크롤 한다.
예제 )
const element = document.querySelector("#box");
element.scrollIntoView(); // 생략하면 기본값 true로 동작한다.
element.scrollIntoView(false);
element.scrollIntoView({block: "end"});
element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
Parameter로 다음과 같은 값을 가진다.
1. alignToTop (Optional)
true
: 요소의 상단이 스크롤 가능한 상위 영역의 맨 위에 정렬되며, true가 기본값이다.false
: 요소의 하단이 스크롤 가능한 상위 영역의 맨 아래에 정렬된다.2. scrollIntoViewOptions (Optional)
behavior (Optional) : 에니메이션을 정의
"auto", "smooth"중 하나 선택, 기본값은 "auto"
block (Optional) : 수직 정렬을 정의
"start", "center", "end", "nearest"중 하나 선택, 기본값은 "start"
inline (Optional) : 수평 정렬을 정함
One of "start", "center", "end", "nearest"중 하나 선택, 기본값은 "nearest"
❗ 참고 자료
https://ko.javascript.info/size-and-scroll-window#page-scroll