해당 포스팅은 생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅임을 미리 알립니다.
이번 포스팅에서는 요소들의 위치와 크기를 알아내보도록 하겠습니다.
자바스크립트 기본 문법 :: 요소의 크기와 위치
우선 엘리먼트의 크기를 알아내는 방법을 알아보도록 하겠습니다.
<style>
body{
padding:0;
margin:0;
}
#target{
width:100px;
height:100px;
border:50px solid #1065e6;
padding:50px;
margin:50px;
}
</style>
<div id="target">
Coding
</div>
<script>
var t = document.getElementById('target');
console.log(t.getBoundingClientRect());
</script>
출력된 문서는 다음과 같습니다.
즉 엘리먼트의 테두리와 body 태그 사이의 거리가 50px입니다.
그리고 테두리를 포함한 엘리먼트의 크기는 300px입니다.
이 값을 알아내고 싶을 때 사용하는 API가 getBoundingClientRect인것입니다.
이를 콘솔에서 실행한 결과는 아래와 같습니다.
즉 엘리먼트의 크기와 위치를 알고 싶을 때는
getBoundingClientRect를 사용하면 됩니다.
참고로 getBoundingClientRect의 width 값을 IE는 제공하지 않습니다.
저는 크롬에서 테스트 하고 있어요.
만약 엘리먼트가 중첩되어 있다면 어떻게 될까요?
위와 같이 엘리먼트를 중첩했을 때 coding 엘리먼트와 문서와의 거리는 200px입니다.
getBoundingClientRect를 호출해봅시다.
<style>
body{
padding:0;
margin:0;
}
div{
border:50px solid #1065e6;
padding:50px;
margin:50px;
}
#target{
width:100px;
height:100px;
}
</style>
<div>
<div id="target">
Coding
</div>
</div>
<script>
var t = document.getElementById('target');
console.log(t.getBoundingClientRect());
console.log(t.offsetParent);
</script>
실행 결과는 아래와 같습니다.
제 노트북이 이상한건지,,, bottom 과 top 값이 왜이럴까요.
정상적이라면 아래와 같이 출력될 겁니다.
즉 엘리먼트의 위치를 의미하는 top, right의 값을 통해서
기준이 그 부모가 아니라 body라는 것을 알 수 있습니다.
그리고 이를 명시적으로 확인할 수 있는 방법은 offsetParent 속성을 호출하는 것입니다.
참고로, 만약 부모 중 CSS position의 값이 static인 td, th, table 엘리먼트가 있다면
이 엘리먼트가 offsetParent가 됩니다.
오래된 브라우저에서는 getBoundingClientRect를 지원하지 않을 수 있기 때문에
이런 경우 offsetLeft와 offsetTop 프로퍼티를 사용합니다.
테두리를 제외한 엘리먼트의 크기를 알고 싶다면 ClientWidth, ClientHeight를 사용하면 됩니다.
<script>
var t = document.getElementById('target');
console.log('clientWidth:', t.clientWidth, 'clientHeight:', t.clientHeight);
</script>
그럼 이렇게 테두리를 제외한 값을 얻을 수 있습니다.
자바스크립트 기본 문법 :: Viewport
요소의 위치를 생각할 때는 사실 조금 더 복잡해집니다.
문서가 브라우저의 크기보다 큰 경우는 스크롤이 만들어지는데,
스크롤에 따라서 위치의 값이 달라지기 때문입니다.
이를 이해하기 위해서는 우선 viewport에 대한 이해가 선행되어야 합니다.
viewport의 좌표
위의 그림처럼 뷰포트는 문서의 내용 중 사용자에게 보여주는 영역을 의미합니다.
이에 따라서 문서의 좌표가 있고, 뷰포트의 자표가 있습니다.
우리가 위에서 살펴본 getBoundingClientRect는 viewport의 좌표를 사용합니다.
<style>
body{
padding:0;
margin:0;
}
div{
border:50px solid #1065e6;
padding:50px;
margin:50px;
}
#target{
width:100px;
height:2000px;
}
</style>
<div>
<div id="target">
Coding
</div>
</div>
<script>
var t = document.getElementById('target');
setInterval(function(){
console.log('getBoundingClientRect : ', t.getBoundingClientRect().top, 'pageYOffset:', window.pageYOffset);
}, 1000)
</script>
위의 예제를 실행해보겠습니다.
setInterval 함수는 첫번째 인자인 함수를 두번째 인자 ms 만큼의 간격을 두고 실행시키는 함수입니다.
첫번째 출력되는 값은, 제가 스크롤을 내리지 않고 그대로 두었을 때의 값입니다.
두번째 부터는 제가 스크롤을 내렸을 때 출력되는 값입니다.
이를 통해서 알 수 있는 것은 getBoundingClientRect의 값이
스크롤에 따라서 달라지는 뷰포트의 좌표를 사용하고 있다는 것입니다.
또한 스크롤의 정도를 알고 싶을 때는 pageYOffset을 사용하면 된다는 것도 알 수 있습니다.
오래된 브라우저에서는 pageYOffset 대신 scrollTop 속성을 사용해야 합니다.
문서의 좌표를 알고 싶다면, 뷰 포트의 좌표에 스크롤된 정도를 더해서 알 수 있습니다.
setInterval(function(){
console.log('getBoundingClientRect : ', t.getBoundingClientRect().top, 'pageYOffset:', window.pageYOffset, 'document y:', t.getBoundingClientRect().top+window.pageYOffset);
}, 1000)
스크롤을 계속 내려도 200이라는 문서 좌표가 출력되는 것을 알 수 있습니다.
자바스크립트 기본 문법 :: 스크롤 변경
아마 화려한 블로그나 잘 정리된 사이트를 가보면 무언가를 클릭했을 때
스크롤의 위치가 변하는 것을 볼 수 있었을겁니다.
이는 scrollLeft 와 scrollTop 프로퍼티를 이용하면 가능합니다.
<style>
body{
padding:0;
margin:0;
}
div{
border:50px solid #1065e6;
padding:50px;
margin:50px;
}
#target{
width:100px;
height:2000px;
}
</style>
<input type="button" id="scrollBtn" value="scroll(0, 1000)" />
<script>
document.getElementById('scrollBtn').addEventListener('click', function(){
window.scrollTo(0, 1000);
})
</script>
<div>
<div id="target">
Coding
</div>
</div>
버튼을 클릭하면 아래쪽으로1000 만큼 스크롤이 내려가는 것을 확인할 수 있습니다.
스크린의 크기는 모니터의 크기와 브라우저 뷰포트의 크기가 있습니다.
이를 알아내려면, 아래 예시와 같이 하면 됩니다.
<script>
console.log('window.innerWidth:', window.innerWidth, 'window.innerHeight:', window.innerHeight);
console.log('screen.width:', screen.width, 'screen.height:', screen.height);
</script>
window.inner*은 뷰포트의 크기를 나타내고, screen.*은 스크린의 크기를 나타냅니다.