Õppige selgeks ResizeObserver API, et täpselt jälgida elementide suuruse muutusi ja luua vastupidavaid, reageerivaid veebipaigutusi. Sukelduge selle eelistesse, kasutusjuhtudesse ja parimatesse tavadesse kaasaegses veebiarenduses.
ResizeObserver API: Täpne elementide suuruse jälgimine dünaamiliste ja reageerivate paigutuste jaoks
Veebiarenduse laias ja pidevalt arenevas maailmas on tõeliselt reageerivate ja kohanduvate kasutajaliideste loomine endiselt esmatähtis väljakutse. Kuigi meediapäringud on pikka aega olnud nurgakiviks paigutuste kohandamisel erinevate vaateakende suurustega, nõuab kaasaegne veeb peenemat lähenemist: reageerimisvõimet komponendi tasandil. Siin astubki mängu võimas ResizeObserver API, mis muudab revolutsiooniliselt seda, kuidas arendajad jälgivad ja reageerivad elemendi suuruse muutustele, sõltumata vaateaknast.
See põhjalik juhend süveneb ResizeObserver API-sse, uurides selle mehaanikat, mitmekesiseid rakendusi, parimaid tavasid ja seda, kuidas see annab arendajatele võimaluse luua ülimalt dünaamilisi ja vastupidavaid veebikogemusi ülemaailmsele publikule.
Põhiprobleemi mõistmine: Miks window.resize jääb hätta
Aastaid oli peamine mehhanism paigutuse muutustele reageerimiseks brauseris window.resize sündmus. Arendajad lisasid sündmuste kuulajaid aknaobjektile, et tuvastada, millal brauseri vaateakna mõõtmed muutusid. Sellel lähenemisel on aga tänapäeva komponendipõhises maailmas olulisi piiranguid:
- Ainult vaateakna-keskne:
window.resizesündmus käivitub ainult siis, kui brauseri aken ise suurust muudab. See ei anna teavet üksikute elementide suuruse muutumise kohta dokumendis muudel põhjustel. - Piiratud ulatus: Komponent võib vajada oma sisemise paigutuse kohandamist, kui selle vanemkonteiner kahaneb või laieneb, isegi kui üldine vaateakna suurus jääb samaks. Mõelge näiteks külgriba kokkutõmbamisele või vahekaardipaneelile, mis avab uut sisu.
window.resizeei paku nende lokaalsete muutuste kohta mingit teavet. - Ebaefektiivne pollimine: Et jälgida elementide tasandi muutusi ilma
ResizeObserver'ita, kasutasid arendajad sageli ebaefektiivseid ja jõudlust nõudvaid pollimismehhanisme, kasutadessetInterval'i, kontrollides korduvaltelement.offsetWidthvõielement.offsetHeight. See põhjustab tarbetuid arvutusi ja potentsiaalset hakeldamist. - Keeruline komponentidevaheline suhtlus: Suuruse muutuste orkestreerimine sügavalt pesastatud või sõltumatute komponentide vahel muutub keeruliseks segaduseks ilma otsese viisita, kuidas komponent saaks teada oma eraldatud ruumi.
Kujutage ette stsenaariumi, kus andmete visualiseerimise graafik peab dünaamiliselt suurust muutma, kui kasutaja kohandab selle sisaldavat <div> elementi, näiteks lohistatava jaoturi abil. window.resize oleks siin kasutu. Just sellise väljakutse lahendamiseks loodigi ResizeObserver.
Sissejuhatus ResizeObserver API-sse
ResizeObserver API pakub jõudsat ja efektiivset viisi elemendi sisu- või ääristekasti suuruse muutuste jälgimiseks. Erinevalt window.resize'ist, mis jälgib vaateakent, keskendub ResizeObserver ühe või mitme siht-DOM-elemendi konkreetsetele mõõtmetele.
See on võimas lisandus veebi-API-de komplekti, mis võimaldab arendajatel:
- Reageerida elemendipõhistele suurusemuutustele: Saada teavitus, kui jälgitava elemendi suurus muutub, sõltumata sellest, kas akna suurus muutus või mitte. See hõlmab muutusi, mis on põhjustatud CSS-i paigutustest (flexbox, grid), dünaamilise sisu lisamisest või kasutaja interaktsioonidest.
- Vältida lõputuid suurusemuutmise tsükleid: API on loodud vältima lõputuid tsükleid, mis võivad tekkida, kui suurusemuutmise sündmuse käsitleja muudaks otse jälgitava elemendi suurust, käivitades uue suurusemuutmise sündmuse. ResizeObserver koondab muudatused ja töötleb neid tõhusalt.
- Parandada jõudlust: Pakkudes deklaratiivset, sündmuspõhist mehhanismi, kaotab see vajaduse kalli pollimise või keeruliste intersection observer'i häkkide järele suuruse jälgimiseks.
- Võimaldada tõelist komponenditaseme reageerimisvõimet: Komponendid saavad tõeliselt teadlikuks oma eraldatud ruumist, mis viib modulaarsemate, korduvkasutatavamate ja vastupidavamate kasutajaliidese elementideni.
Kuidas ResizeObserver töötab: Praktiline süvaanalüüs
ResizeObserver API kasutamine hõlmab mõnda lihtsat sammu: vaatleja instantseerimine, sellele jälgitavate elementide määramine ja seejärel muudatuste käsitlemine tagasikutse funktsioonis.
Instantseerimine ja jälgimine
Esmalt loote uue ResizeObserver'i instantsi, edastades sellele tagasikutse funktsiooni, mis käivitatakse iga kord, kui jälgitava elemendi suurus muutub.
// Looge uus ResizeObserver'i instants
const myObserver = new ResizeObserver(entries => {
// See tagasikutse funktsioon käivitatakse, kui jälgitava elemendi suurus muutub
for (let entry of entries) {
const targetElement = entry.target;
const newWidth = entry.contentRect.width;
const newHeight = entry.contentRect.height;
console.log(`Element ${targetElement.id || targetElement.tagName} muudeti suurusele ${newWidth}px x ${newHeight}px.`);
// Teostage toiminguid uue suuruse põhjal
}
});
Kui teil on vaatleja instants olemas, saate sellele öelda, milliseid DOM-elemente jälgida, kasutades observe() meetodit:
// Hankige element, mida soovite jälgida
const myElement = document.getElementById('myResizableDiv');
// Alustage elemendi jälgimist
if (myElement) {
myObserver.observe(myElement);
console.log('Alustati elemendi myResizableDiv jälgimist.');
} else {
console.error('Elementi #myResizableDiv ei leitud.');
}
Saate sama vaatleja instantsiga jälgida mitut elementi:
const element1 = document.getElementById('chartContainer');
const element2 = document.querySelector('.responsive-sidebar');
if (element1) myObserver.observe(element1);
if (element2) myObserver.observe(element2);
Konkreetse elemendi jälgimise lõpetamiseks kasutage unobserve():
// Lõpetage ühe elemendi jälgimine
if (myElement) {
myObserver.unobserve(myElement);
console.log('Lõpetati elemendi myResizableDiv jälgimine.');
}
Kõigi elementide jälgimise lõpetamiseks ja vaatleja täielikuks lahtiühendamiseks kasutage disconnect():
// Ühendage vaatleja lahti kõigist jälgitavatest elementidest
myObserver.disconnect();
console.log('ResizeObserver on lahti ühendatud.');
Tagasikutse funktsioon ja ResizeObserverEntry
ResizeObserver'ile edastatud tagasikutse funktsioon saab massiivi ResizeObserverEntry objektidest. Iga kirje vastab elemendile, mille suurus on pärast viimast teavitust muutunud.
ResizeObserverEntry objekt pakub olulist teavet suuruse muutuse kohta:
target: Viide DOM-elemendile, mille suurust on muudetud.contentRect:DOMRectReadOnlyobjekt, mis esindab elemendi sisukasti suurust (ala polsterduse ja äärisjoone sees). See on sageli kõige sagedamini kasutatav omadus üldiseks sisu suuruse määramiseks.borderBoxSize:ResizeObserverSizeobjektide massiiv. See annab elemendi ääristekasti mõõtmed, sealhulgas polsterduse ja äärisjoone. Kasulik, kui peate neid oma paigutuse arvutustes arvesse võtma. Iga massiivi objekt sisaldabinlineSizejablockSize.contentBoxSize:ResizeObserverSizeobjektide massiiv, sarnaneborderBoxSize'ile, kuid esindab sisukasti. Seda peetakse kaasaegsemaks ja täpsemaks kuicontentRectsisu mõõtmete jaoks, eriti mitmeveerulistes paigutustes või kirjutusrežiimidega tegelemisel.devicePixelContentBoxSize:ResizeObserverSizeobjektide massiiv, mis pakub sisukasti mõõtmeid seadme pikslites, kasulik pikslitäpseks renderdamiseks, eriti kõrge DPI-ga ekraanidel.
Vaatame näidet, kasutades neid omadusi:
const detailedObserver = new ResizeObserver(entries => {
for (let entry of entries) {
console.log(`--- Muudetud suurusega element: ${entry.target.id || entry.target.tagName} ---`);
// Pärand contentRect (DOMRectReadOnly)
console.log('ContentRect (pärand):');
console.log(` Laius: ${entry.contentRect.width}px`);
console.log(` Kõrgus: ${entry.contentRect.height}px`);
console.log(` X: ${entry.contentRect.x}px`);
console.log(` Y: ${entry.contentRect.y}px`);
// Kaasaegne contentBoxSize (ResizeObserverSize objektide massiiv)
if (entry.contentBoxSize && entry.contentBoxSize.length > 0) {
const contentBox = entry.contentBoxSize[0];
console.log('ContentBoxSize (kaasaegne):');
console.log(` Inline suurus (laius): ${contentBox.inlineSize}px`);
console.log(` Block suurus (kõrgus): ${contentBox.blockSize}px`);
}
// BorderBoxSize (ResizeObserverSize objektide massiiv)
if (entry.borderBoxSize && entry.borderBoxSize.length > 0) {
const borderBox = entry.borderBoxSize[0];
console.log('BorderBoxSize:');
console.log(` Inline suurus (laius koos polsterduse/äärisega): ${borderBox.inlineSize}px`);
console.log(` Block suurus (kõrgus koos polsterduse/äärisega): ${borderBox.blockSize}px`);
}
// DevicePixelContentBoxSize (ResizeObserverSize objektide massiiv)
if (entry.devicePixelContentBoxSize && entry.devicePixelContentBoxSize.length > 0) {
const devicePixelBox = entry.devicePixelContentBoxSize[0];
console.log('DevicePixelContentBoxSize:');
console.log(` Inline suurus (seadme pikslites): ${devicePixelBox.inlineSize}px`);
console.log(` Block suurus (seadme pikslites): ${devicePixelBox.blockSize}px`);
}
}
});
const observeMe = document.getElementById('observeThisDiv');
if (observeMe) {
detailedObserver.observe(observeMe);
}
Märkus contentRect vs. contentBoxSize kohta: Kuigi contentRect on laialdaselt toetatud ja intuitiivne, on contentBoxSize ja borderBoxSize spetsifikatsiooni uuemad lisad. Nad pakuvad ResizeObserverSize objektide massiivi, kuna elemendil võib olla mitu fragmenti, kui see on mitmeveerulises paigutuses. Enamiku tavaliste stsenaariumide puhul, kus on üks fragment, pääsete juurde massiivi esimesele elemendile (nt entry.contentBoxSize[0].inlineSize).
Reaalse maailma kasutusjuhud reageeriva paigutuse haldamiseks
ResizeObserveri rakendused on uskumatult mitmekesised, võimaldades arendajatel luua paindlikumaid ja vastupidavamaid kasutajaliideseid. Siin on mõned veenvad reaalse maailma stsenaariumid:
Dünaamiline graafikute loomine ja andmete visualiseerimine
Graafikute teegid (nagu Chart.js, D3.js, Highcharts jne) peavad sageli oma skaalasid uuesti joonistama või kohandama, kui nende konteiner suurust muudab. Traditsiooniliselt hõlmas see window.resize'i kuulamist ja seejärel käsitsi kontrollimist, kas graafiku vanem on muutunud. ResizeObserveriga saavad graafikud lihtsalt jälgida oma konteinerit ja reageerida otse.
Näide: Armatuurlaud mitme graafikuga, mis on paigutatud ruudustikku. Kui kasutaja muudab paneeli suurust või paigutust, joonistub iga graafik automaatselt uuesti, et sobituda ideaalselt oma uute mõõtmetega, ilma igasuguse virvenduse või käsitsi sekkumiseta.
Kohanduvad ruudustikusüsteemid ja tabelid
Reageerivad tabelid on kurikuulsalt keerulised. Võib-olla soovite peita teatud veerge, teisendada tabeli loenditaoliseks struktuuriks või kohandada veergude laiust vastavalt saadaolevale ruumile. Selle asemel, et tugineda meediapäringutele, mis kehtivad kogu vaateaknale, võimaldab ResizeObserver tabelikomponendil otsustada oma reageerimisvõime üle omaenda laiuse põhjal.
Näide: E-kaubanduse tootekataloogi tabel. Kui selle konteiner muutub kitsaks, võidakse peita spetsiifilised veerud nagu "toote ID" või "laoseis" ning ülejäänud veerud võivad ruumi täitmiseks laieneda. Kui konteiner muutub väga kitsaks, võib tabel isegi muutuda kaardipõhiseks paigutuseks.
Kohandatud kasutajaliidese komponendid ja vidinad
Paljud veebirakendused sisaldavad keerukaid, korduvkasutatavaid kasutajaliidese komponente: külgribad, modaalaknad, lohistatavad paneelid või manustatud vidinad. Need komponendid peavad sageli kohandama oma sisemist paigutust vastavalt neile vanema poolt eraldatud ruumile. ResizeObserver muudab selle isekohanduva käitumise lihtsaks.
Näide: Kohandatud rikastekstiredaktori komponent. See võib kuvada täieliku tööriistariba, kui sellel on piisavalt horisontaalset ruumi, kuid lülitub automaatselt kompaktsemale, hüpikmenüüga vormindusvalikutele, kui selle konteiner kahaneb. Teine näide on kohandatud meediamängija, mis kohandab oma juhtnuppude suurust ja paigutust video konteineri suuruse põhjal.
Reageeriv tüpograafia ja piltide skaleerimine
Lisaks lihtsatele vaateaknapõhistele kohandustele võib ResizeObserver võimaldada tõeliselt sujuvat tüpograafiat ja piltide käsitlemist. Saate dünaamiliselt kohandada fondi suurusi, reavahesid või pildiallikaid (nt laadida suurema eraldusvõimega pilti suuremate konteinerite jaoks) vastavalt tekstiploki või pildikonteineri tegelikule suurusele, mitte ainult akna suurusele.
Näide: Blogipostituse põhisisu ala. Pealkirjade ja lõikude fondi suurus võib peenelt suureneda või väheneda, et optimeerida loetavust sisu veeru konkreetses laiuses, sõltumata külgribast või jalusest.
Kolmandate osapoolte manused ja iframe'id
Iframe'e on kurikuulsalt raske reageerivaks muuta, eriti kui nende sisu peab oma soovitud kõrgusest vanemale lehele teada andma. Kuigi postMessage'i saab kasutada, on see sageli tülikas. Lihtsamate stsenaariumide puhul, kus iframe'i vanem peab reageerima iframe'i välistele suurusemuutustele (nt kui iframe'il on dünaamiline kõrgus selle sisemise sisu põhjal), saab ResizeObserver vanem-ümbrist teavitada.
Näide: Kolmanda osapoole vormi või küsitlustööriista manustamine. Kui vorm dünaamiliselt laieneb või ahendab jaotisi, saab selle sisaldav <div> teie lehel neid suurusemuutusi ResizeObserveri kaudu kuulata ja vastavalt sellele oma stiili või kerimiskäitumist kohandada.
"Konteineripäringu" sarnane käitumine tänapäeval
Enne kui natiivsed CSS-i konteineripäringud laialdaselt toetatud said, oli ResizeObserver peamine viis sarnase loogika saavutamiseks JavaScriptis. Arendajad said jälgida elemendi suurust ja seejärel programmeeritult rakendada CSS-klasse või muuta stiile selle elemendi laiuse või kõrguse lävede põhjal.
Näide: Tootekaardi komponent. Kui selle laius on alla 300 piksli, võib see oma pildi ja teksti vertikaalselt virnastada. Kui selle laius on vahemikus 300 kuni 600 pikslit, võib see need kõrvuti paigutada. Üle 600 piksli võib see näidata rohkem detaile. ResizeObserver pakub käivitajat nendele tingimuslikele stiilirakendustele.
ResizeObserver vs. teised DOM-i jälgimistehnikad
Mõistmine, kuhu ResizeObserver DOM-i API-de ökosüsteemis sobib, on ülioluline. See täiendab, mitte ei asenda, teisi jälgimistehnikaid.
window.resize: Endiselt asjakohane globaalsete paigutuste jaoks
Nagu arutatud, on window.resize kasulik muudatuste jaoks, mis mõjutavad kogu vaateakent, näiteks suuremate paigutusplokkide ümberkorraldamine (nt külgriba nihutamine mobiilis allapoole). Siiski on see ebaefektiivne ja ebapiisav komponenditaseme kohandusteks. Kasutage window.resize'i, kui peate reageerima brauseriakna üldisele suurusele; kasutage ResizeObserver'it konkreetsete elementide mõõtmete jaoks.
MutationObserver: DOM-i struktuuri ja atribuutide muudatuste jaoks
MutationObserver on loodud DOM-puu enda muudatuste jälgimiseks, nagu sõlmede lisamised/eemaldamised, tekstisisu muudatused või atribuutide modifikatsioonid. See ei teata otse elemendi suuruse muutustest. Kuigi DOM-i struktuuri muutus võib kaudselt põhjustada elemendi suuruse muutumist, ei ütleks MutationObserver teile otse uusi mõõtmeid; peaksite need pärast mutatsiooni ise välja arvutama. Selgesõnaliseks suuruse jälgimiseks on ResizeObserver õige tööriist.
Pollimine (setInterval): Suuruse jälgimise anti-muster
Enne ResizeObserverit oli levinud, kuid ebaefektiivne meetod elemendi offsetWidth või offsetHeight korduv kontrollimine setInterval abil. See on üldiselt anti-muster, sest:
- See tarbib asjatult protsessori tsükleid, isegi kui suurusemuutust pole toimunud.
- Pollimisintervall on kompromiss: liiga sage ja see on jõudluse röövel; liiga harv ja kasutajaliides reageerib loiult.
- See ei kasuta brauseri optimeeritud renderdustorustikku paigutuse muudatuste jaoks.
ResizeObserver pakub deklaratiivset, jõudsat ja brauseri optimeeritud alternatiivi.
element.getBoundingClientRect() / element.offsetWidth: Staatilised mõõtmised
Meetodid nagu getBoundingClientRect(), offsetWidth ja offsetHeight pakuvad koheseid, staatilisi mõõtmisi elemendi suurusest ja asukohast nende kutsumise hetkel. Need on kasulikud ühekordseteks mõõtmisteks, kuid ei paku reaktiivsust. Muutuste tuvastamiseks peaksite neid korduvalt kutsuma (nt window.resize käsitleja või pollimistsükli sees), mis viib meid tagasi ebaefektiivsuste juurde, mille ResizeObserver lahendab.
Parimad tavad ja täpsemad kaalutlused
Kuigi võimas, nõuab ResizeObserveri tõhus kasutamine selle nüansside ja potentsiaalsete lõksude mõistmist.
ResizeObserverLoopError vältimine
Levinud viga ResizeObserveri esmakordsel kasutamisel on jälgitava elemendi paigutuse omaduste (nt laius, kõrgus, polsterdus, marginaalid) otsene muutmine selle enda tagasikutse funktsioonis. See võib viia lõputu tsüklini: tuvastatakse suurusemuutus, tagasikutse muudab elemendi suurust, mis käivitab uue suurusemuutuse jne. Brauser viskab lõpuks ResizeObserverLoopError vea, et vältida lehe reageerimast lakkamist.
Lahendus: Lükake paigutuse muudatused edasi requestAnimationFrame'iga.
Jälgitava elemendi paigutuse turvaliseks muutmiseks lükake need muudatused edasi järgmisse animatsioonikaadrisse. See võimaldab brauseril lõpetada praeguse paigutuse läbimise enne, kui teete uusi muudatusi, mis võivad käivitada uue suurusemuutuse.
const saferObserver = new ResizeObserver(entries => {
for (let entry of entries) {
// Veenduge, et me ei muuda siin otse jälgitava elemendi suurust
// Kui peame, peame selle edasi lükkama.
const target = entry.target;
const newWidth = entry.contentRect.width;
// Näide: Kui kohandaksime sihtelemendi fondi suurust selle laiuse põhjal
// HALB: target.style.fontSize = `${newWidth / 20}px`; // Võib põhjustada tsükli
// HEA: Lükake stiilimuudatus edasi
requestAnimationFrame(() => {
// Rakendage muudatusi ainult siis, kui element on endiselt DOM-iga ühendatud
// (oluline, kui elemente saab animatsioonikaadri ajal eemaldada)
if (document.body.contains(target)) {
target.style.fontSize = `${newWidth / 20}px`;
console.log(`Kohandati fondi suurust elemendile ${target.id || target.tagName} väärtusele ${target.style.fontSize}.`);
}
});
}
});
const fontResizer = document.getElementById('fontResizerDiv');
if (fontResizer) {
saferObserver.observe(fontResizer);
}
Oluline on märkida, et see viga tekib tavaliselt siis, kui muudate jälgitavat elementi ennast. Lapselemendi või mitteseotud elemendi muutmine tagasikutses on üldiselt ohutu, kuna see ei käivita uut suurusemuutmise sündmust algselt jälgitaval elemendil.
Jõudlusega seotud mõjud
ResizeObserver on loodud olema väga jõudlusvõimeline. Brauser koondab suurusemuutmise teavitusi, mis tähendab, et tagasikutse funktsiooni kutsutakse välja ainult üks kord kaadri kohta, isegi kui mitu jälgitavat elementi muudavad suurust või üks element muudab suurust mitu korda selle kaadri jooksul. See sisseehitatud piiramine hoiab ära liigsed tagasikutsete täitmised.
Siiski peaksite olema teadlik oma tagasikutse sees tehtavast tööst:
- Kallid arvutused: Vältige raskeid DOM-manipulatsioone või keerulisi arvutusi tagasikutses, kui need pole rangelt vajalikud.
- Paljud vaatlejad: Kuigi tõhus, võib väga suure hulga elementide (nt sadade või tuhandete) jälgimisel siiski olla jõudluse üldkulu, eriti kui iga tagasikutse teeb olulist tööd.
- Varajased väljumised: Kui suurusemuutus ei nõua tegevust, lisage oma tagasikutsesse varajase väljumise tingimus.
Tegevuste jaoks, mis on arvutuslikult kallid ja ei pea toimuma igal suurusemuutmise sündmusel (nt võrgupäringud, keerulised ümberjoonistamised), kaaluge ResizeObserveri tagasikutse poolt käivitatud tegevuste viivitamist või piiramist, mitte tagasikutse enda piiramist. Enamiku kasutajaliidese värskenduste jaoks on sisseehitatud piiramine siiski piisav.
Juurdepääsetavuse kaalutlused
ResizeObserveriga dünaamiliste paigutuste rakendamisel arvestage alati mõjuga juurdepääsetavusele. Veenduge, et paigutuse muudatused:
- On ennustatavad: Vältige äkilisi, desorienteerivaid sisu nihkeid ilma kasutaja algatuseta või selge kontekstita.
- Säilitavad loetavuse: Tekst peab jääma loetavaks ja interaktiivsed elemendid peavad jääma ligipääsetavaks, olenemata konteineri suurusest.
- Toetavad klaviatuurinavigatsiooni: Reageerivad muudatused ei tohiks rikkuda klaviatuuri fookuse järjekorda ega muuta elemente kättesaamatuks.
- Pakuvad alternatiive: Kriitilise teabe või funktsionaalsuse jaoks veenduge, et sellele oleks alternatiivseid juurdepääsuviise, kui dünaamiline suurusemuutus põhjustab selle peitmise või vähem silmapaistvaks muutumise.
Brauseri tugi ja polüfillid
ResizeObserveril on suurepärane brauseritugi kõigis kaasaegsetes brauserites, sealhulgas Chrome, Firefox, Edge, Safari ja Opera. See teeb sellest usaldusväärse valiku kaasaegseks veebiarenduseks.
Projektide jaoks, mis nõuavad ühilduvust vanemate brauseritega (nt Internet Explorer), saab kasutada polüfilli. Teegid nagu resize-observer-polyfill võivad pakkuda vajalikku funktsionaalsust, võimaldades teil API-d järjepidevalt kasutada laiemas keskkondade valikus.
Värskeimat ühilduvuse staatust saate kontrollida aadressil Can I use... ResizeObserver.
Töötamine CSS-i paigutustega (Flexbox, Grid, calc())
ResizeObserver töötab sujuvalt kaasaegsete CSS-i paigutustehnikatega nagu Flexbox ja Grid. Kui elemendi suurus muutub selle vanema flex- või grid-paigutuse reeglite tõttu, käivitab ResizeObserver korrektselt oma tagasikutse. See integratsioon on võimas:
- CSS tegeleb peamise paigutusloogikaga (nt elemendid jaotavad ruumi).
- JavaScript (ResizeObserveri kaudu) tegeleb kõigi sekundaarsete, sisuspetsiifiliste kohandustega, mida CSS üksi ei suuda hallata (nt graafiku ümberjoonistamine, kohandatud kerimisriba radade suuruste dünaamiline kohandamine).
Samamoodi käivitavad elemendid, mille suurused on määratletud CSS-i funktsioonidega nagu calc() või suhteliste ühikutega (em, rem, vw, vh, %), samuti ResizeObserveri, kui nende arvutatud pikslite mõõtmed muutuvad. See tagab, et API on reaktiivne praktiliselt igale mehhanismile, mis mõjutab elemendi renderdatud suurust.
Samm-sammuline näide: Isemuutuva suurusega tekstiala loomine
Vaatame läbi praktilise näite: tekstiala, mis kohandab automaatselt oma kõrgust, et sobituda oma sisuga, ja reageerib seejärel, kui selle vanemkonteineri suurust muudetakse.
Eesmärk on luua <textarea>, mis laieneb vertikaalselt, kui sinna rohkem sisu trükitakse, kuid tagab ka, et selle sisaldav <div> saab mõjutada selle maksimaalset saadaolevat kõrgust, kui konteiner ise suurust muudab.
HTML-i struktuur
Loome lihtsa HTML-struktuuri vanemkonteineri ja selle sees oleva tekstialaga.
<div class="container" id="textContainer">
<h3>Muutuva suurusega sisu ala</h3>
<p>Trükkige siia ja vaadake, kuidas tekstiala kohaneb.</p>
<textarea id="autoResizeTextarea" placeholder="Alustage trükkimist..."></textarea>
<div class="resize-handle"></div>
</div>
CSS-stiilid
Natuke CSS-i, et muuta see visuaalselt selgeks ja võimaldada konteineri käsitsi suuruse muutmist (demonstratsiooniks).
.container {
width: 100%;
max-width: 600px;
min-width: 300px;
min-height: 200px;
background-color: #f0f0f0;
border: 1px solid #ccc;
padding: 15px;
margin: 20px auto;
position: relative;
/* Luba käsitsi suuruse muutmist demo eesmärgil */
resize: both;
overflow: auto;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
border-radius: 8px;
}
.container h3 {
color: #333;
margin-top: 0;
margin-bottom: 10px;
}
.container p {
color: #666;
font-size: 0.9em;
margin-bottom: 15px;
}
#autoResizeTextarea {
width: 100%;
min-height: 50px;
box-sizing: border-box; /* Kaasa polsterdus/ääris laiusesse/kõrgusesse */
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1em;
line-height: 1.5;
font-family: sans-serif;
overflow-y: hidden; /* Peida kerimisriba, haldame kõrgust */
resize: none; /* Keela vaikimisi tekstiala suuruse muutmise käepide */
}
JavaScripti implementatsioon
Nüüd lisame JavaScripti, et muuta tekstiala dünaamiliselt suurust muutvaks.
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('autoResizeTextarea');
const container = document.getElementById('textContainer');
if (!textarea || !container) {
console.error('Vajalikke elemente ei leitud. Kontrollige HTML-i ID-sid.');
return;
}
// Funktsioon tekstiala kõrguse kohandamiseks sisu põhjal
const adjustTextareaHeight = () => {
// Lähtestage kõrgus, et kerimiskõrgust täpselt arvutada
textarea.style.height = 'auto';
// Määrake kõrguseks scrollHeight, tagades, et see mahutab sisu
textarea.style.height = `${textarea.scrollHeight}px`;
// VALIKULINE: Piirake tekstiala kõrgust selle vanemkonteineri sisu kõrgusega
// See takistab tekstialal kasvamast nähtavast konteineri alast suuremaks.
const containerContentHeight = container.clientHeight -
(parseFloat(getComputedStyle(container).paddingTop) || 0) -
(parseFloat(getComputedStyle(container).paddingBottom) || 0);
const currentTextareaHeight = textarea.scrollHeight;
const spaceAboveTextarea = textarea.offsetTop - container.offsetTop;
const maxHeightAllowed = containerContentHeight - spaceAboveTextarea;
if (currentTextareaHeight > maxHeightAllowed && maxHeightAllowed > 0) {
textarea.style.height = `${maxHeightAllowed}px`;
textarea.style.overflowY = 'auto'; // Luba kerimine uuesti, kui see on piiratud
} else {
textarea.style.overflowY = 'hidden'; // Peida kerimine, kui sisu mahub ära
}
};
// 1. Kuulake tekstiala sisendsündmusi, et kohandada kõrgust kasutaja trükkimise ajal
textarea.addEventListener('input', adjustTextareaHeight);
// 2. Kasutage ResizeObserver'it, et reageerida konteineri suuruse muutustele
const containerResizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.target === container) {
console.log(`Konteineri suurus muudeti: ${entry.contentRect.width}px x ${entry.contentRect.height}px`);
// Kui konteineri suurus muutub, peame tekstiala kõrguse uuesti hindama
// eriti kui seda piiras vanema kõrgus.
// Lükake see edasi, et vältida ResizeObserverLoopError'it, kui konteineri lastelemendid mõjutavad selle suurust.
requestAnimationFrame(() => {
if (document.body.contains(container)) {
adjustTextareaHeight();
}
});
}
}
});
// Alustage konteineri jälgimist
containerResizeObserver.observe(container);
// Esialgne kohandamine lehe laadimisel
adjustTextareaHeight();
});
Selles näites:
- Meil on
textarea, mis laiendab oma kõrgust omascrollHeight'i põhjal, kui kasutaja trükib. ResizeObserveron lisatud vanemkonteinerile (#textContainer).- Kui konteineri suurust käsitsi muudetakse (kasutades CSS-i
resize: both;omadust), käivitub vaatleja tagasikutse. - Tagasikutse sees käivitame uuesti
adjustTextareaHeight(). See tagab, et kui konteiner kahaneb, hinnatakse tekstiala kõrguse piirang uuesti, võimaldades potentsiaalselt selle kerimisriba, kui sisu enam ei mahu. - Kasutame
requestAnimationFrame'iadjustTextareaHeight()kutsumiseks vaatleja tagasikutses, et vältida potentsiaalsetResizeObserverLoopError'it, eriti kui tekstiala suurus mõjutaks kuidagi konteineri suurust keerulisemas paigutuses.
See demonstreerib, kuidas ResizeObserver võimaldab komponendil (tekstiala) olla tõeliselt reageeriv mitte ainult oma sisule, vaid ka oma vanema pakutavale dünaamilisele ruumile, luues sujuva ja kasutajasõbraliku kogemuse.
Tulevik: ResizeObserver ja natiivsed konteineripäringud
Natiivsete CSS-i konteineripäringute (nt @container reeglid) tulekuga, mis saavad laialdast brauserituge, tekib levinud küsimus: kas ResizeObserveril on endiselt oma roll?
Vastus on kindel jah.
- Konteineripäringud: Keskenduvad peamiselt CSS-põhisele stiilimisele, mis põhineb vanemkonteineri suurusel. Need võimaldavad teil rakendada stiile (nagu
display,font-size,grid-template-columnsmuutmine) otse CSS-i reeglites ilma JavaScriptita. See on ideaalne puhtalt esitlus- ja paigutusega seotud reageerimisvõime jaoks. - ResizeObserver: Paistab silma, kui vajate JavaScripti reageerimiseks suuruse muutustele. See hõlmab:
- Lõuendi programmeeritud ümberjoonistamine (nt graafikud, mängud).
- Keerulise JavaScripti-põhise kasutajaliidese loogika kohandamine (nt kolmanda osapoole teegi uuesti lähtestamine, lohistatavate elementide uute asukohtade arvutamine).
- Suhtlemine teiste JavaScripti API-dega suuruse põhjal (nt erineva suurusega piltide dünaamiline laadimine, video taasesituse juhtimine).
- Kui vajate täpseid pikslimõõtmeid arvutusteks, mida CSS üksi ei suuda pakkuda või tõhusalt teostada.
Sisuliselt tegelevad konteineripäringud deklaratiivse stiilimisega, samas kui ResizeObserver tegeleb imperatiivse, programmeeritud loogikaga. Need on täiendavad tööriistad, mis koos loovad ülima tööriistakomplekti tõeliselt reageerivate veebirakenduste jaoks.
Kokkuvõte
ResizeObserver API on asendamatu tööriist kaasaegsetele veebiarendajatele, kes püüdlevad tõeliselt dünaamiliste ja reageerivate kasutajaliideste loomise poole. Pakkudes tõhusat, sündmuspõhist mehhanismi mis tahes DOM-elemendi suuruse muutuste jälgimiseks, viib see meid kaugemale vaateakna-keskse reageerimisvõime piirangutest ja robustse, komponenditaseme kohanemisvõime valdkonda.
Alates andmete visualiseerimiste sujuvast kohandamisest nende konteineritega kuni iseteadlike kasutajaliidese komponentide võimaldamiseni, annab ResizeObserver teile võimu luua vastupidavamaid, jõudlusvõimelisemaid ja kasutajasõbralikumaid veebikogemusi. Võtke see võimas API omaks, et tõsta oma front-end arendust, luua paigutusi, mis kohanevad graatsiliselt igas kontekstis, ja pakkuda erakordseid digitaalseid tooteid ülemaailmsele publikule.
Alustage ResizeObserveri integreerimist oma projektidesse juba täna ja avage uus kontrollitase oma reageerivate veebidisainide üle!