개발 기술/사소하지만 놓치기 쉬운 개발 지식

[JS] 크기 변화를 감지하는 두 가지 방법(resize, ResizeObserver)

by GicoMomg (Lux) 2022. 3. 26.

🤔 화면 크기나 특정 요소의 크기가 변할 때, 그 변화를 감지할 수 있을까? 이번 시간에는 화면과 요소의 크기 변화를 감지하는 방법을 알아보았다.


1. resize, 브라우저 크기에 반응

1) resize 이벤트란?

window.addEventListener("resize", function() {
  // window resize시 처리
})
  • resize 이벤트는 브라우저의 크기가 변경될 때 발생한다.
  • 만약, 브라우저 크기 변화에 따른 dom의 변경 크기를 구하려면 getBoundingClientRect(), getComputedStyle()를 사용해줘야한다.

2) 예시

  • 아래 예시는 브라우저 크기를 변경한 뒤, div의 변화된 너비를 화면에 출력했다.

See the Pen resize example by KumJungMin (@kumjungmin) on CodePen.






2. ResizeObserver, 모든 요소에 반응

💡 그런데, 특정 요소의 크기 변화는 감지할 수 없는걸까? 그럴 때는 resize가 아닌, ResizeObserver를 사용해보자!

1) ResizeObserver이란?

  • ResizeObserver는 Resize(크기 변경) + Observer(관찰자)를 말하는데,
  • resize 이벤트와 달리 브라우저는 물론 특정 dom의 크기 변화를 감지할 수 있다.
  • 또한 resize에서는 변경된 크기를 구하기 위해 getBoundingClientRect()를 써야했지만, ResizeObserver에서는 변화된 크기를 제공해준다.

2) ResizeObserver API

(1) new ResizeObserver()

var ro = new ResizeObserver(entries => {
  for (let entry of entries) {
    // 관찰 대상의 resize이벤트시, 처리할 로직
  }
});
  • 요소의 resize를 감지하기 위해선, ResizeObserver를 생성해야 한다.
  • ResizeObserver 콜백 함수에는 관찰할 대상 요소(ResizeObserverEntry)를 넘겨준다.

(2) entry.contentRect

var ro = new ResizeObserver(entries => {
  for (let entry of entries) {
    const cr = entry.contentRect;     // this
    console.log('Element:', entry.target);
    console.log(`Element size: ${cr.width}px x ${cr.height}px`);
    console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
  }
});
  • ResizeObserver 콜백 함수에선 contentRect를 사용해 요소의 크기, 위치 정보 등을 제공받을 수 있다.
  • 요소의 크기의 경우, contentRect & padding 크기를 제공하지만,
  • 실제로 ResizeObserver는 요소의 contentRect크기 변화만을 관찰(감지)한다.

(2) ResizeObserver.disconnect()

  • ResizeObserver가 관찰(감지)하는 모든 대상을 감지 해제한다.
btn.addEventListener('click', () => {  // 버튼 클릭 이벤트 발생시
  resizeObserver.disconnect();         // 해당 옵저버의 요소 크기 감지 해제
})

(3) ResizeObserver.observe()

  • ResizeObserver가 특정 대상에 대한 관찰(감지)을 시작한다.
  • ResizeObserver객체를 만든 후 실행시켜줘야, 사이즈 감지가 가능하다.
resizeObserver.observe(target, options);             // 기본 형태
resizeObserver.observe(el, { box : 'border-box' });  // 예시
  • 옵션은 observer가 변경사항을 감지할 box-model을 설정할 수 있다.
  • box옵션에는 content-box, border-box, device-pixel-content-box가 있는데,
  • content-box는 요소의 콘텐츠 영역이며, border-box는 요소의 테두리 영역이다.
  • device-pixel-content-box는 디바이스의 픽셀단위 기준 요소의 콘텐츠 영역을 말한다.

(4) ResizeObserver.unobserver()

  • ResizeObserver가 특정 대상에 대한 관찰(감지)을 해제한다.
resizeObserver.observe(el);



3) 예시

(1) 요소의 크기 감지

  • 먼저, textarea의 크기를 변경하여 화면에 너비, 높이를 출력해보았다.

See the Pen ResizeObserver (1) by KumJungMin (@kumjungmin) on CodePen.


(2) 여러 요소의 크기 감지

  • 여러 개의 textarea의 크기 변경을 감지하도록, forEach 반복문을 사용해보았다.

See the Pen ResizeObserver (2) by KumJungMin (@kumjungmin) on CodePen.


(3) 요소 추가로 인한 크기 감지

  • appendChild를 사용해, 관찰 대상 요소에 자식을 추가해보았다.
  • 자식이 추가되어, 관찰 대상 요소의 크기가 변했을 때도 감지하는지 예시를 보자.

See the Pen ResizeObserver(3) by KumJungMin (@kumjungmin) on CodePen.


반응형

댓글