ResizeObserver
Wywołuje funkcję za każdym razem, gdy zmieni się rozmiar obserwowanego elementu, bez względu na przyczynę zmiany.
- Zwraca
- Nowy obiekt
ResizeObserver.
Przykład
#const panel = document.querySelector('#panel')
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const border = Math.round(entry.borderBoxSize[0].inlineSize)
const content = Math.round(entry.contentRect.width)
console.log(`Panel: ${border} px, treść: ${content} px`)
}
})
observer.observe(panel)Pierwsze powiadomienie podaje rozmiar zaraz po rozpoczęciu obserwacji. contentRect nie obejmuje dopełnienia i ramki, dlatego jest o 26 px węższy. Przeciągnij prawy dolny róg panelu w podglądzie, a konsola pokaże każdą zmianę.
Definicja i zastosowanie
#ResizeObserver powiadamia o zmianie rozmiaru konkretnego elementu. Zdarzenie resize na window mówi tylko o zmianie okna, a element może zmienić rozmiar także z innych powodów: po dodaniu treści, zwinięciu panelu bocznego albo zmianie klasy. Obserwator wychwyci każdy z tych przypadków.
Funkcja zwrotna dostaje tablicę obiektów ResizeObserverEntry. Pole contentRect zawiera szerokość i wysokość obszaru treści (bez dopełnienia i ramki), a borderBoxSize i contentBoxSize podają rozmiary jako tablice obiektów z polami inlineSize (szerokość przy zwykłym, poziomym tekście) i blockSize (wysokość).
Jeśli element jest wyświetlony, pierwsze wywołanie nastąpi zaraz po rozpoczęciu obserwacji, więc od razu poznasz aktualny rozmiar. Metoda observe() dodaje element, unobserve() go usuwa, a disconnect() kończy obserwację. Opcja box pozwala wybrać, który rozmiar ma być śledzony, np. { box: "border-box" }.
Uważaj na zmienianie rozmiaru obserwowanego elementu wprost w funkcji zwrotnej. Nowego rozmiaru nie da się już zgłosić w tej samej klatce, więc przeglądarka zgłasza błąd „ResizeObserver loop completed with undelivered notifications”, a powiadomienie przychodzi dopiero w następnej klatce. Takie zmiany od razu odłóż na później, np. przez requestAnimationFrame().
Składnia
#new ResizeObserver(callback)
observer.observe(element)
observer.observe(element, { box })
observer.unobserve(element)
observer.disconnect()Parametry
#callback
function (entries, observer)
Funkcja wywoływana po zmianie rozmiaru. Dostaje tablicę wpisówResizeObserverEntry.box
opcjonalny, napis (w observe())
Który rozmiar śledzić:"content-box"(domyślnie),"border-box"albo"device-pixel-content-box".
Więcej przykładów
#const card = document.querySelector('#card')
const nextWidths = ['300px', '200px']
const observer = new ResizeObserver(([entry]) => {
const width = Math.round(entry.borderBoxSize[0].inlineSize)
card.classList.toggle('wide', width >= 280)
console.log(`${width} px, szeroki układ: ${card.classList.contains('wide')}`)
const next = nextWidths.shift()
if (next) {
setTimeout(() => {
card.style.width = next
})
}
})
observer.observe(card)Szerokość zmieniamy automatycznie, żeby pokazać kolejne powiadomienia. Każdą zmianę odkładamy przez setTimeout(), bo zmiana rozmiaru wprost w funkcji zwrotnej wywołałaby błąd pętli. W prawdziwej aplikacji rozmiar zmienia się np. po zwinięciu panelu bocznego.
Obsługa przeglądarek
#Szeroko dostępne · od 2020 roku
Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.
- Chrome
- Edge
- Firefox
- Safari
Dobre praktyki
#- Do reagowania na rozmiar elementu wybieraj
ResizeObserverzamiast zdarzeniaresizenawindow. Element może zmienić rozmiar także wtedy, gdy okno ma stały rozmiar. - W funkcji zwrotnej nie zmieniaj rozmiaru obserwowanego elementu bezpośrednio. Odłóż zmianę do następnej klatki albo zmieniaj tylko to, co nie wpływa na rozmiar, np. kolor.
- Jeśli chodzi tylko o dopasowanie stylów do szerokości kontenera, rozważ zapytania kontenera w CSS (
@container). Wtedy JavaScript nie jest potrzebny.
Powiązane hasła
#- IntersectionObserverObserwuje, czy element jest widoczny w oknie albo w przewijanym kontenerze, i wywołuje funkcję, gdy to się zmienia.
- MutationObserverObserwuje zmiany w drzewie DOM: dodane i usunięte elementy, zmiany atrybutów i tekstu, i zgłasza je w jednej funkcji.
- Element.getBoundingClientRect()Zwraca rozmiar elementu i jego położenie względem widocznego obszaru okna w postaci obiektu DOMRect.
- requestAnimationFrame()Planuje wywołanie funkcji tuż przed kolejnym odświeżeniem ekranu. Służy do płynnych animacji sterowanych JavaScriptem.
- Element.classListObiekt do dodawania, usuwania, przełączania i sprawdzania klas CSS elementu.
Widzisz błąd albo brakuje przykładu? Napisz do nas.