ResizeObserver: 요소의 document.onresize와 유사

ResizeObserver는 요소의 크기가 변경되는 시점을 알려줍니다.

ResizeObserver 이전에는 리스너를 문서의 resize에 연결해야 했습니다. 이벤트를 전달하여 표시 영역 크기의 변경에 대한 알림을 받습니다. 일정 핸들러에서 제공된 경우 코드의 영향을 받은 요소를 적절하게 반응하도록 특정 루틴을 호출합니다. 필요한 경우 요소의 새 크기를 변경하려면 getBoundingClientRect() 또는 getComputedStyle()(레이아웃의 원인이 될 수 있음) 모든 읽기와 모든 데이터를 일괄 처리하는 쓰기 작업을 수행합니다

기본 스레드 없이 요소의 크기가 변경되는 사례도 다루지 않았습니다. 창 크기가 조절된 것을 볼 수 있습니다. 예를 들어 새 하위 항목을 추가하거나 요소의 display 스타일을 none로 설정하거나 유사한 작업이 요소, 동위 요소 또는 그 상위에 있을 수 있습니다.

이러한 이유로 ResizeObserver가 유용한 프리미티브입니다. Kubernetes는 변경 원인과 관계없이 관측된 요소의 크기를 조정합니다. 관찰된 요소의 새로운 크기에도 액세스할 수 있습니다.

브라우저 지원

  • Chrome: 64. <ph type="x-smartling-placeholder">
  • Edge: 79. <ph type="x-smartling-placeholder">
  • Firefox: 69. <ph type="x-smartling-placeholder">
  • Safari 13.1. <ph type="x-smartling-placeholder">

소스

API

위에서 언급한 Observer 접미사가 있는 모든 API는 간단한 API를 공유합니다. 있습니다. ResizeObserver도 예외는 아닙니다. ResizeObserver 객체 만들기 생성자에 콜백을 전달합니다. 콜백에는 ResizeObserverEntry 객체(관찰된 요소당 하나의 항목) 에는 요소의 새 크기가 포함됩니다.

var ro = new ResizeObserver(entries => {
  for (let entry of entries) {
    const cr = entry.contentRect;

    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`);
  }
});

// Observe one or multiple elements
ro.observe(someElement);

세부정보

어떤 내용이 신고되나요?

일반적으로 ResizeObserverEntry 드림 는 contentRectDOMRectReadOnly 객체를 지정합니다. 콘텐츠 상자는 콘텐츠를 배치할 수 있는 상자입니다. 그것은 테두리 상자에서 패딩을 뺀 값입니다.

CSS 상자 모델의 다이어그램

ResizeObserver는 두 측정기준을 모두 보고합니다. contentRect과 패딩의 경우 contentRect감시합니다. contentRect를 요소의 경계 상자와 혼동하지 마세요. 경계 getBoundingClientRect()에 의해 보고된 상자는 전체 요소와 그 하위 요소에 적용됩니다. SVG는 규칙의 예외로, ResizeObserver는 경계 상자의 크기를 보고합니다.

Chrome 84부터 ResizeObserverEntry에 자세히 알아볼 수 있습니다. 이러한 각 속성은 ResizeObserverSize을 반환합니다. blockSize 속성과 inlineSize 속성이 포함된 객체입니다. 이 콜백이 호출될 때 관찰된 요소에 관한 정보입니다.

  • borderBoxSize
  • contentBoxSize
  • devicePixelContentBoxSize

이러한 항목은 모두 읽기 전용 배열을 반환합니다. 향후에는 여러 프래그먼트가 있는 요소를 지원할 수 있습니다. 다중 열 시나리오입니다. 현재 이러한 배열에는 하나의 요소만 포함됩니다.

이러한 속성에 대한 플랫폼 지원은 제한적이지만 Firefox는 이미 지원 첫 번째 두 개는

언제 신고되나요?

사양에 따라 ResizeObserver는 모든 크기 조절 이벤트를 처리해야 합니다. 페인트 전과 레이아웃 후에 있습니다. 이렇게 하면 ResizeObserver의 콜백이 페이지 레이아웃을 변경할 수 있는 이상적인 장소입니다. 이유: ResizeObserver 처리는 레이아웃과 페인트 사이에 발생하므로, 이렇게 하면 페인트가 아니라 레이아웃을 사용합니다.

확인

관측값의 크기를 변경하면 어떻게 되는지 궁금할 수 있습니다. 요소가 ResizeObserver에 관한 콜백 내에서 이루어지고 있나요? 정답은 즉시 콜백에 대한 또 다른 호출을 생성합니다. 다행히 ResizeObserver에는 무한 콜백 루프와 순환 종속 항목을 피하기 위한 메커니즘을 제공합니다. 변경사항은 크기가 조절된 요소가 DOM에서 더 깊은 경우에만 동일한 프레임에서 처리됩니다. 트리를 생성합니다. 그러지 않으면 다음 프레임으로 지연됩니다.

애플리케이션

ResizeObserver를 사용하면 요소별 구현을 구현할 수 있습니다. 지정할 수 있습니다. 요소를 관찰함으로써 요소의 스타일을 변경할 수 있습니다. 다음에서 , 두 번째 상자 는 너비에 따라 테두리 반경을 변경합니다.

const ro = new ResizeObserver(entries => {
  for (let entry of entries) {
    entry.target.style.borderRadius =
        Math.max(0, 250 - entry.contentRect.width) + 'px';
  }
});
// Only observe the second box
ro.observe(document.querySelector('.box:nth-child(2)'));

살펴볼 만한 또 다른 흥미로운 예는 채팅 창입니다. 발생하는 문제 일반적인 위에서 아래로 대화 레이아웃에서 스크롤 포지셔닝입니다 피해야 할 사항 창이 하단에 놓여 있는 것이 가장 최근 메일이 표시됩니다. 또한 모든 종류의 레이아웃 (휴대전화가 가로 모드에서 세로 모드로 또는 그 반대로 바뀌는 것을 생각해 보세요.) 동일한 효과를 얻을 수 있습니다.

ResizeObserver을 사용하면 하나의 코드를 두 가지 시나리오에 모두 해당할 수 있습니다 창 크기 조절은 ResizeObserver가 할 수 있는 이벤트입니다. appendChild()를 호출하면 해당 요소의 크기도 조절됩니다. (overflow: hidden가 설정되지 않은 경우) 새 요소 이 점을 고려하면 몇 줄이면 원하는 결과를 얻을 수 있습니다. 효과:

const ro = new ResizeObserver(entries => {
  document.scrollingElement.scrollTop =
    document.scrollingElement.scrollHeight;
});

// Observe the scrollingElement for when the window gets resized
ro.observe(document.scrollingElement);

// Observe the timeline to process new messages
ro.observe(timeline);

꽤 깔끔하죠?

여기서부터 사용자가 스크롤을 내린 경우를 처리하기 위해 코드를 추가할 수 있습니다. 새 메시지가 도착하면 스크롤하여 해당 메시지가 계속 표시되도록 하고 싶은 경우 도움이 됩니다.

또 다른 사용 사례는 자체 레이아웃을 실행하는 모든 종류의 맞춤 요소에 대한 사용 사례입니다. ResizeObserver까지는 하위 요소를 다시 배치할 수 있도록 크기가 변경됩니다.

다음 페인트에 대한 상호작용 효과 (INP)

다음 페인트에 대한 상호작용 (INP)은 사용자 상호작용에 대한 페이지의 전반적인 응답성입니다. 페이지의 INP가 '좋은' 기준점—즉, 200 밀리초 이하입니다. 페이지가 페이지에 안정적으로 응답하지만 상호작용을 나타냅니다

이벤트에 대한 응답으로 이벤트 콜백을 실행하는 데 사용자 상호작용은 상호작용의 총 지연 시간에 상당히 영향을 미칠 수 있습니다. INP에서 고려해야 할 유일한 측면은 아닙니다. 또한 INP는 상호작용의 다음 페인트가 발생하는 데 걸리는 시간 이것은 사용자를 업데이트하는 데 필요한 렌더링 작업에 걸리는 시간 인터페이스 3을 생성합니다.

ResizeObserver의 경우 이것이 중요한 이유는 ResizerObserver 인스턴스는 렌더링 작업 직전에 실행됩니다. 이 이는 콜백에서 발생하는 작업을 그렇게 하면 계정의 기본 결제 수단을 구성할 수 있습니다.

ResizeObserver에서 필요한 만큼 렌더링 작업을 적게 합니다. 과도한 렌더링 작업으로 인해 브라우저가 지체될 수 있습니다 예를 들어 ResizeObserver 콜백이 실행되도록 하는 콜백이 있는 경우 원활한 사용 환경을 위해 다음 사항을 준수해 주시기 바랍니다.

  • CSS 선택자가 최대한 단순해야 합니다. 과도한 스타일 재계산 작업을 사용할 수 있습니다. 스타일 재계산은 레이아웃 직전에 발생하며 복잡한 CSS 선택자는 지연 시간을 최소화합니다
  • 다음 트리거가 발생할 수 있는 ResizeObserver 콜백에서는 작업을 피합니다. 강제 리플로우.
  • 페이지 레이아웃을 업데이트하는 데 필요한 시간은 일반적으로 페이지의 DOM 요소 개수입니다. 이는 페이지에서 ResizeObserver: ResizeObserver 콜백에서 실행된 작업은 다음과 같을 수 있습니다. 보다 높아질 수 있다는 것을 알 수 있습니다.

결론

ResizeObserver모든 주요 언어로 제공됩니다. 브라우저 요소에서 요소 크기 변경을 모니터링할 수 있는 효율적인 방법을 제공합니다. 있습니다. 이 강력한 API로 렌더링을 너무 지연시키지 않도록 주의하세요.