필자는 얼마전에 JS에서 HTML 요소의 크기를 가져와서 계산해야하는 일이 발생했다. 예전에 어렴풋이 사용한 기억이 있어서, IDE의 코드 자동완성기능을 믿고, 그냥 element.width라고 쳐보니 많은 속성들이 나왔다.
속성이 여러개가 있다는 것은 분명 차이가 있을것이고 제품에서는 정확한 결과를 내야하기 때문에 이 차이들을 알 필요가 있다. 알아보자.
1. element.offsetWidth (Height)
element.offsetWidth는 margin을 제외한, padding값, border값까지 계산한 값을 가져온다. (일반적으로 많이쓰임)
아래의 코드를 보자
<style>
*{margin: 0;box-sizing: border-box;}
.asdf{
width: 100px;
height: 100px;
margin: 30px;
padding: 20px;
border: 10px solid #20c997;
background-color: #22b8cf;
color: #fff;
overflow: scroll;
}
</style>
<div class="asdf">글씨글씨글씨글씨글씨글씨글씨글씨</div>
<div class="result"></div>
<script>
let div = document.querySelector('.asdf');
let result = document.querySelector('.result');
result.innerText = div.offsetWidth + 'x' + div.offsetHeight;
</script>
실행을 시켜 보면
위와같이 margin을 제외한 초록색 부분까지의 크기, padding값과 border값이 포함된 크기가 가져와졌다.
내부 width, height가 83이 뜨는것은 스크롤바때문이다. 크롬기준 스크롤바는 약 17px이다.
2. element.clientWidth (Height)
element.clientWidth는 margin값과 border값이 제외된, padding값까지만 적용된 내부의 실제 크기를 가져온다.
border(테두리)는 외부에 속한다.
아래의 코드를 보자
<style>
*{margin: 0;}
.asdf{
width: 100px;
height: 100px;
margin: 30px;
padding: 20px;
border: 10px solid #20c997;
background-color: #22b8cf;
color: #fff;
overflow: scroll;
}
</style>
<div class="asdf">글씨글씨글씨글씨글씨글씨글씨글씨</div>
<div class="result"></div>
<script>
let div = document.querySelector('.asdf');
let result = document.querySelector('.result');
result.innerText = div.clientWidth + 'x' + div.clientHeight;
</script>
사실 위의 코드와 달라진 것은 offsetWidth, offsetHeight가 clientWidth, clientHeight가 되었다는 것 뿐이다.
아무튼 결과는 아래와 같다.
보면 margin값과 border값이 빠진 padding값만 반영이 되어서 나온것을 볼 수 있다.
사실 좀더 자세히 말자하면 scroll bar의 크기도 빠져있다.
따라서 실제 파란색 크기만 가져와진 것이다.
3. element.scrollWidth (Height)
element.scrollWidth (Height)는 스크롤 영역일때
스크롤로 감싸여진 내용의 전체 크기를 가져온다.
아래의 코드를 보자
<style>
*{margin: 0;}
.asdf{
width: 100px;
height: 100px;
margin: 30px;
padding: 20px;
border: 10px solid #20c997;
background-color: #22b8cf;
color: #fff;
overflow: scroll;
}
</style>
<div class="asdf">글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨</div>
<div class="result"></div>
<script>
let div = document.querySelector('.asdf');
let result = document.querySelector('.result');
result.innerText = div.scrollWidth + 'x' + div.scrollHeight;
</script>
스크롤을 더 크게만들기 위해서 글씨를 더 썼다.
결과는
위와같다.
clientWidth (Height)처럼 파란부분의 크기를 가져왔지만, 스크롤로 가려진 전체크기가 가져와진 것을 알 수 있다.
4. element.getBoundingClientRect();
이번엔 설명하기 귀찮다. 그냥 아래의 코드를 보자.
<style>
*{margin: 0;}
.asdf{
width: 100px;
height: 100px;
margin: 30px;
padding: 20px;
border: 10px solid #20c997;
background-color: #22b8cf;
color: #fff;
overflow: scroll;
}
</style>
<div class="asdf">글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨</div>
<div class="result"></div>
<script>
let div = document.querySelector('.asdf');
let result = document.querySelector('.result');
result.innerText = div.getBoundingClientRect();
console.log(div.getBoundingClientRect());
</script>
일단 기본적으로 top, right, bottom, left ,x ,y는 중학교 이상의 학력의 사람이라면 그냥 보기만해도 뭔지 알것이며, 본문 에서 설명하려는 것과는 상관이 없으므로 설명하지 않겠다.
일단 지금 width, height를 봤을때는 offsetWidth (Height)와 결과가 같다.
그러나 이 함수는 랜더링된 결과를 가져온다.
아래의 코드를 보자.
<style>
*{margin: 0;}
.asdf{
width: 100px;
height: 100px;
margin: 30px;
padding: 20px;
border: 10px solid #20c997;
background-color: #22b8cf;
color: #fff;
overflow: scroll;
transform: scale(1.2);
}
</style>
<div class="asdf">글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨글씨</div>
<div class="result"></div>
<script>
let div = document.querySelector('.asdf');
let result = document.querySelector('.result');
result.innerText = div.offsetWidth + 'x' + div.offsetHeight;
console.log(div.getBoundingClientRect());
</script>
.asdf 박스에 transform: scale(1.2);를 주었다. 1.2배로 늘렸다.
result에는 offsetWidth (Height)를 출력했고, console에는 getBoundingClientRect함수의 실행결과를 출력했다.
결과는 아래와 같다.
getBoundingClientRect함수의 실행결과는 실제 랜더링 크기이다.
아까 1.2배를 늘렸기 때문에 160 * 1.2 한 결과와 같이 192가 나온 것이다.
이 함수의 width, height는 현재 사용되고있는 대부분의 브라우저에서 사용이 가능하다. 킹터넷 갓스플로러에서도 x, y는 몰라도 width, height만큼은 사용이 가능하니 적절히 잘 사용하자.
여기까지 헷갈리는 여러가지 HTML 요소의 크기를 구하는 방법을 살펴보았다.
특히 저 스크롤바가 적폐다.
그럼 ㅅㄱ
'푸로그래밍 > JS' 카테고리의 다른 글
[JS] if 대신 사용이 가능한 연산자, 삼항 연산자란? (0) | 2019.11.08 |
---|---|
[JS] Array 관련 매소드 Array.prototype.forEach (0) | 2019.11.06 |
[JS] 화살표 함수 Arrow Function (2) | 2019.10.29 |
[JS] ES6 구조분해할당 (0) | 2019.10.25 |