Dimenzije i pozicija DOM HTML elementa
U današnjoj lekciji ćemo naučiti kako da otkrijemo dimenzije i poziciju elementa. Znamo da pozicija i dimenzije elementa na stranici mogu zavisiti od različitih faktora koje definišemo putem CSS atributa.
Element | ||
---|---|---|
clientWidth | r | Širina vidljivog sadržaja elementa. |
clientHeight | r | Visina vidljivog sadržaja elementa. |
clientLeft | r | Debljina levog bordera. |
clientTop | r | Debljina gornjeg bordera. |
scrollWidth | r | Širina sadržaja elementa koji se može skrolovati uključujući i padding |
scrollHeight | r | Visina sadržaja elementa koji se može skrolovati uključujući i padding |
scrollLeft | rw | Broj piksela koliko je element skrolovan po horizontali |
scrollTop | rw | Broj piksela koliko je element skrolovan po vertikali |
scrollIntoView(top) | - | Prikaz elementa u vidljivom okviru nadređenog elementa. |
HTMLElement | ||
offsetWidth | r | Širina elementa uključujući i bordere. |
offsetHeight | r | Visina elementa uključujući i bordere. |
offsetParent | r | Nadređeni referentni element u odnosu na koji je element pozicioniran. |
offsetLeft | r | Horizontalna udaljenost leve ivice od leve ivice offsetParent objekta. |
offsetTop | r | Vertikalna udaljenost gornje ivice od gornje ivice offsetParent objekta. |
Da bismo saznali vrednost određenog formatiranja, možemo posegnuti za podobjektom style, ali vodite računa o sledećim ograničenjima:
- Podobjekat style je definisan samo za HTMLElement objekte. Ovo nam u najvećem broju slučajeva neće praviti problem, pošto najčešće i radimo sa HTML elementima.
- Svojstva ppodobjekta style imaju vrednost samo ako su negde eksplicitno definisana. Znači, ako nigde nismo odredili npr. širinu elementa, ne možemo je ni saznati na ovaj način.
Bitna razlika između svojstava i metoda koje ovde obrađujemo u odnosu na CSS svojstva podobjekta style je što su vrednosti u CSS-u stringovi, koji osim numeričke veličine imaju i jedinicu mere, dok sva ovde opisana svojstva i metodi vraćaju numerčke vrednosti. To bi značilo npr:
element.scrollWidth --> 150
element.style.width --> "150px"
Najveći broj ovde prikazanih svojstava služe samo za čitanje vrednosti. Ako želimo nešto da promenimo, moramo to raditi preko odgovarajućih svojstava podobjekta style.
Svojstva koja ovde obrađujemo nisu jedini način da saznamo dimenzije elementa, ali su svakako najefikasniji.
Objekat Element
clientWidth
clientHeight
Ova dva svojstva sadrže dimenzije elementa u pikselima, s tim što predstavljaju širinu i visinu dela u kome se prikazuje sadržaj. To znači da obuhvataju dimenzije sadržaja i unutrašnjih margina.
Ove veličine u potpunosti odgovaraju vrednostima CSS atributa koji utiču na dimenzije elementa. Vrednost ovih svojstava se računa na sledeći način:
clientWidth = width + levi i desni padding
clientHeight = height + gornji i donji padding
Ne zaboravite da se način na koji se ove vrednosti računaju može promeniti ako se koristi drugačiji box model.
Ova svojstva se mogu samo čitati. Ako želimo da menjamo dimnezije elementa, moramo koristiti podobjekat style (samo ako je objekat sa kojim radimo istovremeno i HTMLElement objekat). O direktnom menjanju stila objekta pomoću JavaScripta ste mogli da čitate u tekstu DOM objekti.
sirina = element.clientWidth;
visina = element.clientHeight;
element.style.width = [širina] + "px";
element.style.height = [visina] + "px";
element.style.padding = "[nove dimenzije]";
element.style.paddingTop = [veličina] + "px";
...
clientTop
clientLeft
Svojstva clientTop i clientLeft vam verovatno neće često trebati. Ipak, ona predtavljaju udaljenost sadržaja od spoljne ivice elementa. U prevodu, to je debljina gornjeg, odnosno levog bordera.
Postoji samo jedan izuzetak - ako je sadržaj naveden pismom koje se piše s desna na levo (npr. arapski jezik), vertikalni scroll-bar će biti postavljen sa leve strane. U tom slučaju će vrednost svojstva clientLeft obuhvatati širinu bordera i širinu scroll-bara.
Ova svojstva se takođe mogu samo čitati. Ako želimo da menjamo njihove vrednosti, moramo promeniti veličine levog i gornjeg okvira:
element.style.borderTopWidth = [veličina] + "px";
element.style.borderLeftWidth = [veličina] + "px";
scrollWidth
scrollHeight
Ova svojstva predstavljaju širinu i visinu "skrolabilnog" sadržaja. Iz CSS lekcije o kontroli prikaza elementa znamo da, ako sadržaj elementa prevazilazi njegove dimenzije, postoje tri mogućnosti, koje definišemo overflow atributima:
- sadržaj će se "preliti" van elementa
- deo sadržaja koji prevazilazi element će biti sakriven
- element može omogućiti skrolovanje sadržaja
U svakom od ovih slučajeva, svojstva scrollWidth i scrollHeight daju rezultat koji je suštinski jednak veličini sadržaja sa paddingom.
scrollWidth = širina sadržaja + levi padding + desni padding
scrollHeight = visina sadržaja + gornji padding + donji padding
Ova svojstva se mogu samo čitati. Ako želimo da menjamo dimnezije elementa, moramo koristiti podobjekat style (pod uslovom da objekat nasleđuje i HTMLElement interfejs).
Inače, uvek se uzima u obzir ceo element, bio on vidljiv ili ne, što znači da dobijamo punu širinu i visinu čak iako je deo sadržaja sakriven.
scrollTop
scrollLeft
Ova svojstva u stvari predstavljaju broj piksela za koliko je sadržaj elementa skrolovan, ako je skrolovanje uopšte moguće. Ako nije, vrednosti ovih svojstava će uvek biti 0.
Svojstva scrollTop i scrollLeft su jedina koja danas opisujemo a da im je moguće promeniti vrednost. To znači da pomoću JavaScripta možemo zadati koliko će sadržaj elementa biti skrolovan unutar svog okvira.
element.scrollTop = [broj piksela];
scrollIntoView()
Recimo da sadržaj prevazilazi okvir elementa i potrebno ga je skrolovati, takođe, pretpostavimo da postoji određeni elemenat koji se nalazi u delu sadržaja koji se trenutno ne vidi, Metod scrollIntoView() će zahtevati od web čitača da element na kome se primenjuje "dovede" u vidljivi deo okvira. Dakle, element ovim metodom praktično "primorava" korisnika da ga vidi.
Za razliku od svojstava scrollTop i scrollLeft koja utiču na skrolovanje sadržaja samog elementa, metod scrollIntoView() utiče na skrolovanje sadržaja kontejnerskog elementa.
Ovaj metod ima jedan parametar koji prihvata logičku vrednost i koja označava da li će element da se "dovede" do vrha (true) ili do dna (false) kontejnerskog elementa. Ako se parametar ne navede, podrazumeva se vrednost false.
element.scrollIntoView([poravnanje po vrhu]);
element.scrollIntoView();
element.scrollIntoView(true);
Inače, čak i kada zadamo da element bude doveden "do vrha", to ne mora da se desi. Sve zavisi od položaja samog elementa unutar sadržaja. Ako je element na dnu, ne posotji nikakv način da se "doskroluje" do vrha kontejnera.
Skrolovanje u vidljivi deo kontejnera će se izvršiti čak iako ne postoje scroll-barovi (zadato npr. overflow:hidden u CSS-u).
Pomoću ovog metoda, možemo na stranici simulirati unutrašnje linkove (one za koje bismo inače navodili "tarabu").
Objekat HTMLElement
offsetWidth
offsetHeight
Ova dva svojstva takođe sadrže dimenzije elementa u pikselima, s tim što predstavljaju širinu i visinu - koliko element zauzima mesta u dokumentu. To znači da obuhvataju dimenzije sadržaja, unutrašnjih margina i okvira. Ove veličine u potpunosti odgovaraju vrednostima CSS atributa koji utiču na dimenzije elementa. Ne zaboravite da postoje dva moguća podešavanja box modela:
- content-box - CSS širina i visina se odnose na sadržaj
- border-box - CSS širina i visina se odnose na ceo vidljivi deo elementa
U prvom slučaju, kada je zadat content-box model (to je i default vrednost), vrednost ovih svojstava odgovara sledećoj računici:
offsetWidth = width + levi i desni padding + levi i desni border
offsetHeight = height + gornji i donji padding + gornji i donji border
Ako se zada border-box, dimenzije se računaju kao:
offsetWidth = width
offsetHeight = height
Drugim rečima, okreni-obrni, offsetWidth i offsetHeight uvek predstavljaju dimenzije elementa zaključno sa borderom. Na njih čak ne utiče ni to da li sadržaj elementa izlazi van okvira, da li se vidi ili ne, da li postoje scroll-barovi i sl. Ove vrednosti se mogu samo čitati, ne i menjati. Ako želimo da promenimo dimenzije elementa, koristićemo njegov podobjekat style.
offsetParent
Svojstvo offsetParent, predstavlja referencu na nadređeni element u DOM hijerarhiji, u odnosu na koji je ovaj elemenat pozicioniran. Ovo svojstvo je usko povezano sa CSS pozicioniranjem. Da vidimo šta je referenttni elemenat za različite vrednosti CSS atributa position:
- static - statičko pozicioniranje znači da je offsetParent prvi nadređeni element
- relative - i u ovom slučaju, offsetParent je prvi nadređeni element
- absolute - ovde je, kao što je definisano i u CSS-u, offsetParent prvi nadređeni nestatički pozicionirani element
- fixed - pri fiksnom pozicioniranju, offsetParent je, naravno element body
offsetTop
offsetLeft
Konačno dolazimo i do poslednja dva svojstva za danas. Svojstva offsetTop i offsetLeft predstavljaju poziciju elementa u odnosu na njegov offsetParent. To su praktično "koordinate" elementa po gornjoj i levoj ivici.
Pogledajte priloženu sliku. Videćete da ako se sadržaj nadređenog elementa može skrolovati, da se time ne menja pozicija po ovim svojstvima. Jednostavno, to su "koordinate" elementa u odnosu na početak sadržaja, a ne vidljivi okvir nadelementa.
U pitanju su numeričke vrednosti u pikselima, koje se mogu samo čitati.
Primeri
Pozicija elementa u odnosu na vidljivi okvir
Hajde da odmah razrešimo kako bismo dobili poziciju elementa u odnosu na vidljivi okvir nadelementa, a ne u odnosu na početak njegovog sadržaja. Ovo ima smisla raditi samo u situaciji kada sadržaj nadelementa prevazilazi njegovu veličinu, pa je potrebno skrolovanje.
var left = elem.offsetLeft - elem.offsetParent.scrollLeft;
var top = elem.offsetTop - elem.offsetParent.scrollTop;
Od pozicije koju element ima u nadelementu, oduzimamo broj piksela za koji je nadelement eventualno skrolovan.
Pozicija elementa na stranici
Pronalaženje pozicije elementa na stranici nije trivijalan zadatak, kako bismo pomislili na početku. Element može biti unutar nadelementa koji je unutar nad-nadelementa i tako dalje, sve dok se ne stigne do samog dokumenta.
Ne zaboravite da svojstva offsetLeft i offsetTop vraćaju "koordinate" samo u odnosu na nadelement.
var element = obj;
var left = element.offsetLeft;
var top = element.offsetTop;
while (element = element.offsetParent) {
left += element.offsetLeft;
top += element.offsetTop;
}
U primeru, želimo da otkrijemo poziciju objekta obj. Prvo, pravimo privremenu referencu elem na njega. Zatim beležimo inicijalne koordinate left i top u odnosu na referentni element.
Ono što moramo da uradimo, je da uđemo u while ciklus koji se "vrti" sve dok postoji offsetParent element koji "ubacujemo" u referencu elem. Na koordinate left i top dodajemo koordinate svakog sledećeg nivoa u hijerarhiji.
Ako želimo da uzmemo u obzir i da li sadržaj nekog od nadlemenata skrolovan, moramo malo da zakomplikujemo:
var elem = obj;
var left = elem.offsetLeft - (elem.offsetParent ? elem.offsetParent.scrollLeft : 0);
var top = elem.offsetTop - (elem.offsetParent ? elem.offsetParent.scrollTop : 0);
while (elem = elem.offsetParent) {
left += elem.offsetLeft - (elem.offsetParent ? elem.offsetParent.scrollLeft : 0);
top += elem.offsetTop - (elem.offsetParent ? elem.offsetParent.scrollTop : 0);
}
Isprobajte i sami kako funkcioniše.
Postavljanje elementa u centar
Evo trika kako možemo da postavimo bilo koji element u centar ekrana. Inače bismo za ovo koristili window.innerWidth i window.innerHeight, ali ovde ćemo pokazati "zaobilaznicu".
Prvo treba da pripremimo CSS. Naša "merna jedinica" mora da bude element koji je fiksno pozicioniran "od ivice do ivice" prozora. Taj stil smo grupisali pod klasom fullwin. Za element koji želimo da bude u centru prozora, koristimo fiksno pozicioniranje. To je element koji je u ovom primeru identifikovan kao "centar".
<style>
.fullwin {
position: fixed;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
}
#centar {
position: fixed;
...
}
</style>
<div id="centar"></div>
Evo šta onda radimo u JavaScriptu:
var elem = document.getElementById("centar");
var win = document.createElement("div");
win.className = "fullwin";
document.body.appendChild(win);
elem.style.top = (win.clientHeight - elem.offsetHeight) / 2 + "px";
elem.style.left = (win.clientWidth - elem.offsetWidth) / 2 + "px";
document.body.removeChild(win);
Prvo pravimo referencu elem na element koji želimo da smestimo u centar. Onda kreiramo privremeni elemenat win, koji će nam služiti kao "etalon" da izmerimo prozor web čitača. Znači dodeljujemo mu klasu "fullwin" koja će ga "razvući" preko celog prozora. Onda ga dodajemo na stranicu.
Sada dolaze najvažnije stvari - koristimo podobjekat style objekta elem kako bismo mu dodelili top i left poziciju. Za vertikalu, od polovine unutrašnje visine objekta win oduzimamo polovinu spoljašnje visine ojekta elem. Na tu koordinatu samo dodajemo "px", pošto je u pitanju CSS vrednost. Na isti način računamo horizontalnu koordinatu.
Na kraju, uklanjamo objekat win - poslužio je svrsi.
Pogledajte sve to na "živom" primeru.
- Mozilla Developer Network, Element
- Mozilla Developer Network, HTMLElement