웹브라우저 JavaScript

문서의 기하학적 특성

이번 시간에는 요소들의 위치와 크기를 알아내는 방법을 배운다. 

요소의 크기와 위치

우선 엘리먼트의 크기를 알아내는 방법을 살펴보자. (실행)

<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>

실행 결과는 아래와 같다.

즉 엘리먼트의 위치를 의미하는 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의 좌표를 사용한다. 

아래 예제를 실행해보면 1초에 한번씩 getBoundingClientRect의 top 속성과 window.pageYOffset의 값이 출력된다. (실행)

<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>

이를 통해서 알 수 있는 것은 getBoundingClientRect의 값이 스크롤에 따라서 달라지는 뷰포트의 좌표를 사용하고 있다는 것이다. 또한 스크롤의 정도를 알고 싶을 때는 pageYOffset을 사용하면 된다는 것도 알 수 있다. 

오래된 브라우저에서는 pageYOffset 대신 scrollTop 속성을 사용해야 한다.

문서의 좌표

그럼 문서의 좌표를 알고 싶으면 어떻게 해야 하나? 뷰포트의 좌표에 스크롤된 정도를 더해서 알 수 있다. 아래와 같이 코드를 조금 수정했다. (실행)

setInterval(function(){
	console.log('getBoundingClientRect : ', t.getBoundingClientRect().top, 'pageYOffset:', window.pageYOffset, 'document y:', t.getBoundingClientRect().top+window.pageYOffset);
}, 1000)

스크롤

그럼 문서의 스크롤 값을 변경하는 것은 어떻게 하는 것일까? 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>

스크린의 크기

스크린의 크기는 모니터의 크기와 브라우저 뷰포트의 크기가 있다. 이를 알아내는 방법은 아래와 같다. (실행)

<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.*은 스크린의 크기를 나타낸다.

참고

두개의 viewport에 대하여

댓글

댓글 본문
작성자
비밀번호
  1. tachyon
    감사합니다
  2. JustStudy
    2016.07.12 화
    고맙습니다 3.
  3. JustStudy
    2016.07.12 화
    고맙습니다 3.
  4. JustStudy
    2016.,07.02 토
    고맙습니다 2.
  5. 이주환
    2016. 04. 28
    잘보고 갑니다~!
  6. JustStudy
    고맙슴니다
  7. WayneKing
    가자 가자
  8. 참빛바다
    http://codeflow.co.kr/ 사이트 자체가 접속이 안되네요
  9. 쥬슈야
    여기에서 따라 움직이는 배너나 메뉴버튼에 대한 단서가 나오는군요. 항상 감사합니다.
    그리고 참고 "두개의 viewport에 대하여" 링크는 연결이 안되는군요. 링크수정이 필요할 것으로 보입니다.
  10. 코딩!
    감사합니다!
  11. 호두과자
    정말정말 감사합니다!!!
  12. 머머
    저번에 알려주신 해시랑 스크롤투랑 기능이 비슷하네요!
  13. 육점이
    감사합니다~!!!
  14. 규빈이아빠
    좀 헷갈리네요. 반복해서 들어봐야겠네요. 감사합니다^^
  15. 알아갈수록
    이리 저리 돌아댕기다가 여기서 좋은 정보알아가네요^^ 감솨합니다~
  16. Daniel
    고생하셨습니다^^ 소개해주신 codeflow란 곳도 참 좋군요. 다만 관리를 안하는지, 광고게이들의 글로 도배된 모습이 참으로 안타깝습니다...
버전 관리
egoing
현재 버전
선택 버전
graphittie 자세히 보기