[jQuery to Vanilla JS] 2. jQuery height 함수를 Vanilla JS로 migration

2020. 5. 20. 17:08Front-end/Vanilla JS

300x250
반응형

Vanilla JS와 jQuery의 너비, 높이를 조회하는 방법은 차이가 있습니다.
Vanilla JS를 이용하여 Element의 높이를 조회하는 방법을 알아보고, 기존에 jQuery로 작성한 코드를 migration하는 방법을 알아봅시다.

※ 너비(width)와 높이(height)는 규칙이 동일하므로 너비에 관한 설명은 생략합니다.


  1. 테스트 환경
  2. Element의 height 관련 프로퍼티
    1. innerHeight : 내부높이
    2. offestHeight : 실제높이
    3. scrollHeight : 스크롤높이
  3. jQuery height 함수를 Vanilla JS로 migration
    1. height()
    2. innerHeight()
    3. outerHeight(), outerHeight(true)

1. 테스트 환경

*,*::before,*::after { box-sizing: border-box;}
body{ margin: 0 }
section { display: grid; }
section .d-out {
    margin: 13px;
    padding: 11px;
    border: 3px solid gold;
    width: 200px;
    height: 200px;
    overflow-y: auto;
}
section .d-out .d-inn {
    padding: 18px;
    margin: 10px;
    width: 600px;
    height: 400px;
    border: 2px solid pink;
}
#d02, #d02 .d-inn, #d03, #d03 .d-inn { box-sizing: content-box;}
#d01 .d-inn { background-color: #bbbbbb;}
#d02 .d-inn { background-color: #4a9c5a;}
#d03 .d-inn { background-color: #095057; width: 200px;}
<section>
	<div id="d01" class="d-out">
		<div class="d-inn">d01</div>
	</div>
	<div id="d02" class="d-out">
		<div class="d-inn">d02</div>
	</div>
	<div id="d03" class="d-out">
		<div class="d-inn">d03</div>
	</div>
</section>

우리는 d-out class 가 설정된 첫번째 div 요소의 높이를 구해볼 것입니다.

d-out은 margin(바깥 여백): 13px, padding(내부 여백): 11px, border(테두리,골드): 3px 설정이 되어있습니다.
d-inn은 margin(바깥 여백): 10px, padding(내부 여백): 18px, border(테두리,핑크): 2px 설정이 되어있습니다.

box-sizing 속성이 border-box일 경우, border(테두리)까지를 기준으로 width/height를 잡고
content-box일 경우, content까지를 기준으로 width/height를 잡습니다.

margin collapse 방지를 위해 section의 display속성을 table로 설정했습니다.

※ 테스트 환경은 Chrome 최신 버전 입니다.


22

화면에 출력된 모습입니다.


2. Element의 height 관련 프로퍼티

getElementById를 이용하여 d01 ~ d03 id가 설정된 div의 높이를 구해봅시다.

참고로 Vanilla JS에서 제공하는 height관련 프로퍼티와 jQuery에서 제공하는 height관련 함수는 조회 기준이 다릅니다.

Vanilla JS에서는 현재 보여지는 컨텐츠 영역이나 실질적 컨텐츠 영역에 관한 height를 표현하는 반면,
jQuery는 컨텐츠에 패딩, 테두리, 마진의 포함/미포함에 따른 height를 표현합니다.

만일 jQuery를 이용하여 Element의 height관련 프로퍼티를 조회하고 싶다면 .prop(프로퍼티명)을 이용하면 됩니다.


2-1) clientHeight

Element의 기본 프로퍼티 중 하나입니다.
조회하고자 하는 Element의 화면상에 보여지는 실질적 컨텐츠 높이로 Element 높이에서 테두리, 스크롤 높이 를 뺀 높이입니다.

스크롤 바 높이는 브라우저별로 다르기 때문에, clientHeight값 역시 브라우저별로 다를 수 있습니다.( Chrome: 17px, Edge: 16px )

$('#d01').prop('clientHeight');    // jQuery

document.getElementById('d01').clientHeight;  // Vanilla JS

14

box-sizing: border-boxd01은 border까지 포함해서 200px이지만,
box-sizing: content-boxd02, d03은 컨텐츠 높이가 200px이기 때문에(border, padding미포함) 계산방식이 다릅니다.


2-2) offsetHeight

HTMLElement의 기본 프로퍼티 중 하나입니다.
기준 Element의 화면상에 보여지는 높이로, 테두리나 스크롤 높이를 빼지 않습니다.

$('#d01').prop('offsetHeight');
$('#d01').outerHeight(); // jQuery

document.getElementById('d01').offsetHeight; // Vanilla JS

15


2-3) scrollHeight

Element의 기본 프로퍼티 중 하나입니다.
기준 Element의 컨텐츠의 총 높이로, Element의 높이에 비해 컨텐츠의 길이가 커져 스크롤이 생겼을 시, 스크롤에 가려져 있는 컨텐츠의 총높이를 조회합니다.
기준 Element의 padding값과 내부 Element의 총 높이 및 margin을 더한 높이입니다.

$('#d01').prop('scrollHeight'); // jQuery

document.getElementById('d01').scrollHeight; // Vanilla JS

16

d02, d03의 내부도 box-sizing: content-box 이기 때문에, .d-inn의 height가 컨텐츠에 적용되어 border및 padding을 따로 더해줘야함을 잊지 마세요.


3. jQuery height 함수를 Vanilla JS로 migration

Vanilla JS에서는 height를 재는 기준이 Element가 view에 육안으로 보이는 높이를 기준으로 조회가 되었습니다.
(Element의 높이에서 테두리나 스크롤 높이를 뺀 높이라던가. Element 내부의 컨텐츠의 실질적 높이와 같이)

jQuery에는 height, innerHeight, outerHeight라는 함수를 제공하는데, 그중 .outerHeight()는 Vanilla JS의 offsetHeight 프로퍼티와 동일하게 작동하지만, 높이를 조회하는 방식이 상이합니다.


jQuery에서는 margin, border, padding 속성을 포함하느냐 안포함하느냐로 height를 표현하며, scroll의 높이는 height계산과 상관없습니다.

21


3-1) height()

컨텐츠의 높이를 조회합니다.
조회할 Element의 높이(offsetHeight)에서 테두리(border)와 padding을 뺀 값입니다.
이때 주의할 점은, box-sizing: content-box 일 때에는 스크롤바 높이도 빼야한다 는 점입니다.

17

$(".d-out:eq(0)").height(); // jQuery
function getHeight(el) {
  var c = window.getComputedStyle(el);
  var border = parseFloat(c.borderTopWidth) + parseFloat(c.borderBottomWidth),
      padding = parseFloat(c.paddingTop) + parseFloat(c.paddingBottom);
  var scrollBar = el.offsetHeight - el.clientHeight - border;

  if(c.boxSizing == "border-box") {
    return el.offsetHeight - border - padding;
  } else {
    return el.offsetHeight - border - padding - scrollBar;
  }
}

getHeight(document.getElementById('d01')); // Vanilla JS

※ window 객체의 getComputedStyle 함수를 이용하면 Element에 설정된 style을 가져올 수 있습니다.


3-2) innerHeight()

조회할 Element의 높이(offsetHeight)에서 테두리(border) 높이만 뺀 값입니다.

18

$(".d-out:eq(0)").innerHeight();
function getInnerHeight(el) {
  var c = window.getComputedStyle(el);
  var border = parseFloat(c.borderTopWidth) + parseFloat(c.borderBottomWidth);

  return el.offsetHeight - border;
}

getInnerHeight(document.getElementById('d01')); // Vanilla JS

3-3) outerHeight(), outerHeight(true)

outerHeight()는 border까지의 높이로 offsetHeight와 같은 기능입니다.
outerHeight(true)는 offsetHeight에 margin을 더하면 되는데, height()함수 때 처럼 box-sizing: content-box 일 때에는 스크롤바 높이도 빼야한다 는 점에서 차이점이 있습니다.

19

$(".d-out:eq(0)").outerHeight(); // jQuery

document.getElementById('d01').offsetHeight; // Vanilla JS

※ 아래에서 생성한 함수를 이용해도 됩니다.
getOuterHeight(document.getElementById('d01'));


20

$(".d-out:eq(0)").outerHeight(true); // jQuery

function getOuterHeight(el, includeMargin) {
  includeMargin = includeMargin || false;
  var c = window.getComputedStyle(el);
  var margin = parseFloat(c.marginTop) + parseFloat(c.marginBottom),
  border = parseFloat(c.borderTopWidth) + parseFloat(c.borderBottomWidth);
  var scrollBar = el.offsetHeight - el.clientHeight - border;
  if(includeMargin) {
    if(c.boxSizing == "border-box") {
      return el.offsetHeight + margin;
    } else {
      return el.offsetHeight + margin - scrollBar;
    }
  }
  return el.offsetHeight;
}

getOuterHeight(document.getElementById('d01'), true); // Vanilla JS
300x250
반응형