JavaScript obsahuje mnoho vlastnostÃ, které nám umožÅujà naÄÃtat informace o Å¡ÃÅce, výšce a jiných geometrických vlastnostech elementu.
Äasto je potÅebujeme, když v JavaScriptu pÅemisÅ¥ujeme nebo umisÅ¥ujeme elementy.
Ukázkový element
Jako ukázkový element, na nÄmž budeme tyto vlastnosti pÅedvádÄt, budeme použÃvat následujÃcà element:
<div id="pÅÃklad">
...Text...
</div>
<style>
#pÅÃklad {
width: 300px;
height: 200px;
border: 25px solid #E8C48F;
padding: 20px;
overflow: auto;
}
</style>
Má ohraniÄenà (border), vnitÅnà okraje (padding) i rolovánà (scrolling), tedy celou sadu vlastnostÃ. Nejsou v nÄm vnÄjšà okraje (margin), jelikož ty nejsou souÄástà samotného elementu, a proto pro nÄ neexistujà speciálnà vlastnosti.
Element vypadá takto:
Můžete si otevÅÃt dokument na pÃskoviÅ¡ti.
Uvedený obrázek zobrazuje nejsložitÄjšà pÅÃpad, kdy element obsahuje posuvnÃk. NÄkteré prohlÞeÄe (ne vÅ¡echny) si pro nÄj rezervujà mÃsto, které berou z obsahu (na obrázku oznaÄeno jako âÅ¡ÃÅka obsahuâ).
Bez posuvnÃku by tedy Å¡ÃÅka obsahu byla 300px, ale jestliže je Å¡ÃÅka posuvnÃku 16px (na různých zaÅÃzenÃch a prohlÞeÄÃch se Å¡ÃÅka může liÅ¡it), zbude jen 300 - 16 = 284px, což bychom mÄli brát v úvahu. Proto pÅÃklady v této kapitole pÅedpokládajÃ, že element obsahuje posuvnÃk. Bez nÄj jsou nÄkteré výpoÄty jednoduššÃ.
padding-bottom může být zaplnÄna textemNa naÅ¡ich obrázcÃch budou vnitÅnà okraje obvykle zobrazeny prázdné, ale pokud element obsahuje vÄtšà množstvà textu a ten pÅeteÄe, prohlÞeÄ bÄžnÄ zobrazuje âpÅetékajÃcÃâ text v dolnÃm vnitÅnÃm okraji padding-bottom.
Geometrie
NásledujÃcà obrázek obsahuje pÅehled vÅ¡ech geometrických vlastnostÃ:
Hodnoty tÄchto vlastnostà jsou technicky ÄÃsla, ale tato ÄÃsla jsou âv pixelechâ, jsou to tedy pixelové mÃry.
ZaÄnÄme tyto vlastnosti prozkoumávat od vnÄjÅ¡ku elementu.
offsetParent, offsetLeft/Top
Tyto vlastnosti jsou zapotÅebà jen zÅÃdka, ale jsou to ty ânejvÃce vnÄjÅ¡Ãâ geometrické vlastnosti, proto zaÄneme u nich.
Vlastnost offsetParent obsahuje nejbližšÃho pÅedka, kterého prohlÞeÄ použÃvá k výpoÄtu souÅadnic pÅi vykreslovánÃ.
Je to nejbližšà pÅedek, který je jednÃm z následujÃcÃch:
- má umÃstÄnà v CSS (
positionjeabsolute,relative,fixednebosticky), nebo <td>,<th>nebo<table>, nebo<body>.
Vlastnosti offsetLeft/offsetTop poskytujà souÅadnice x/y vzhledem k levému hornÃmu rohu pÅedka offsetParent.
V následujÃcÃm pÅÃkladu je offsetParent vnitÅnÃho <div> element <main> a offsetLeft/offsetTop se poÄÃtajà od jeho levého hornÃho rohu (180):
<main style="position: relative" id="hlavnÃ">
<article>
<div id="pÅÃklad" style="position: absolute; left: 180px; top: 180px">...</div>
</article>
</main>
<script>
alert(pÅÃklad.offsetParent.id); // hlavnÃ
alert(pÅÃklad.offsetLeft); // 180 (poznámka: je to ÄÃslo, ne ÅetÄzec "180px")
alert(pÅÃklad.offsetTop); // 180
</script>
Je nÄkolik pÅÃpadů, kdy offsetParent je null:
- U nezobrazených elementů (majÃ
display:nonenebo nejsou v dokumentu). - U
<body>a<html>. - U elementů obsahujÃcÃch
position:fixed.
offsetWidth/Height
PÅejdÄme nynà k samotnému elementu.
Tyto dvÄ vlastnosti jsou nejjednoduššÃ. Poskytujà âvnÄjÅ¡Ãâ Å¡ÃÅku/výšku elementu, nebo jinými slovy jeho úplnou velikost vÄetnÄ ohraniÄenÃ.
Pro náš ukázkový element:
offsetWidth = 390â vnÄjšà šÃÅka, lze vypoÄÃtat jako souÄet vnitÅnà CSS Å¡ÃÅky (300px), vnitÅnÃch okrajů (2 * 20px) a ohraniÄenà (2 * 25px).offsetHeight = 290â vnÄjšà výška.
Geometrické vlastnosti se poÄÃtajà jen pro zobrazené elementy.
Jestliže element (nebo nÄkterý z jeho pÅedků) má display:none nebo nenà v dokumentu, pak jsou vÅ¡echny jeho geometrické vlastnosti nulové (nebo null v pÅÃpadÄ offsetParent).
Když jsme napÅÃklad vytvoÅili element, ale jeÅ¡tÄ jsme ho nevložili do dokumentu anebo tento element nebo nÄkterý z jeho pÅedků má display:none, pak offsetParent je null a offsetWidth, offsetHeight jsou 0.
Toho můžeme využÃt ke zjiÅ¡tÄnÃ, zda element je skrytý, napÅÃklad takto:
function jeSkrytý(elem) {
return !elem.offsetWidth && !elem.offsetHeight;
}
ProsÃme vÅ¡imnÄte si, že taková funkce jeSkrytý vracà true i pro elementy, které jsou na obrazovce, ale jejich velikost je nulová.
clientTop/Left
UvnitÅ elementu máme ohraniÄenÃ.
K jeho zmÄÅenà sloužà vlastnosti clientTop a clientLeft.
V naÅ¡em pÅÃkladu:
clientLeft = 25â Å¡ÃÅka levého ohraniÄenÃclientTop = 25â Å¡ÃÅka hornÃho ohraniÄenÃ
â¦Abychom vÅ¡ak byli pÅesnÃ: tyto vlastnosti neobsahujà šÃÅku a výšku ohraniÄenÃ, ale relativnà souÅadnice vnitÅnà Äásti vzhledem k vnÄjšà Äásti.
Jaký je v tom rozdÃl?
UvidÃme jej, když budeme mÃt dokument Ätený zprava doleva (operaÄnà systém je v arabském nebo hebrejském jazyce). PosuvnÃk pak nenà napravo, ale nalevo a clientLeft pak zahrnuje i Å¡ÃÅku posuvnÃku.
V takovém pÅÃpadÄ clientLeft nebude 25, ale i se Å¡ÃÅkou posuvnÃku 25 + 16 = 41.
PÅÃklad v hebrejÅ¡tinÄ:
clientWidth/Height
Tyto vlastnosti poskytujà velikost plochy ležÃcà uvnitÅ ohraniÄenà elementu.
Obsahujà šÃÅku obsahu spoleÄnÄ s vnitÅnÃmi okraji, ale bez posuvnÃku:
Na uvedeném obrázku se nejprve vÄnujme vlastnosti clientHeight.
Nenà tu vodorovný posuvnÃk, takže je to pÅesnÄ souÄet toho, co je uvnitÅ ohraniÄenÃ: výška z CSS 200px plus hornà a dolnà vnitÅnà okraj (2 * 20px), celkem 240px.
Nynà clientWidth â Å¡ÃÅka obsahu zde nenà 300px, ale 284px, protože 16px zabÃrá posuvnÃk. SouÄet je tedy 284px plus levý a pravý vnitÅnà okraj, celkem 324px.
Pokud element nemá vnitÅnà okraje, pak clientWidth/Height je pÅesnÄ Å¡ÃÅka a výška obsahu, ležÃcÃho uvnitÅ ohraniÄenà a posuvnÃku (pokud tam je).
Když tedy nemáme vnitÅnà okraje, můžeme použitÃm clientWidth/clientHeight zjistit velikost plochy obsahu.
scrollWidth/Height
Tyto vlastnosti se podobajà clientWidth/clientHeight, ale zahrnujà i odrolované (skryté) Äásti:
Na uvedeném obrázku:
scrollHeight = 723â je celá vnitÅnà výška plochy obsahu vÄetnÄ odrolovaných ÄástÃ.scrollWidth = 324â je celá vnitÅnà šÃÅka, vodorovné rolovánà zde nemáme, takže je rovnaclientWidth.
Pomocà tÄchto vlastnostà můžeme zvÄtÅ¡it element na celou jeho Å¡ÃÅku a výšku.
TÅeba takto:
// zvÄtÅ¡Ãme element na celou výšku jeho obsahu
element.style.height = `${element.scrollHeight}px`;
KliknutÃm na tlaÄÃtko zvÄtÅ¡Ãte element:
scrollLeft/scrollTop
Vlastnosti scrollLeft/scrollTop jsou Å¡ÃÅka/výška skryté, odrolované Äásti elementu.
Na následujÃcÃm obrázku vidÃme scrollHeight a scrollTop pro blok se svislým rolovánÃm.
Jinými slovy, scrollTop udává, âkolik bylo odrolovánoâ.
scrollLeft/scrollTop mohou být mÄnÄnyVÄtÅ¡ina zde uvedených geometrických vlastnostà sloužà pouze pro ÄtenÃ, ale scrollLeft/scrollTop se dajà mÄnit. ProhlÞeÄ pak bude rolovat elementem.
Jestliže kliknete na následujÃcà element, spustà se kód elem.scrollTop += 10, který způsobÃ, že obsah elementu odroluje o 10px dolů.
sem
1
2
3
4
5
6
7
8
9
Nastavenà scrollTop na 0 nebo na obrovskou hodnotu, napÅ. 1e9, způsobÃ, že element odroluje až ke svému hornÃmu nebo dolnÃmu okraji.
Nezjišťujte Å¡ÃÅku a výšku z CSS
PrávÄ jsme uvedli geometrické vlastnosti DOM elementů, pomocà nichž můžeme zjišťovat Å¡ÃÅky a výšky a vypoÄÃtávat vzdálenosti.
Jak ale vÃme z kapitoly Styly a tÅÃdy, můžeme naÄÃtat CSS výšku a Å¡ÃÅku funkcà getComputedStyle.
ProÄ tedy nenaÄÃst Å¡ÃÅku elementu funkcà getComputedStyle, napÅÃklad takto?
let elem = document.body;
alert( getComputedStyle(elem).width ); // zobrazà CSS Å¡ÃÅku elementu
ProÄ bychom mÃsto toho mÄli použÃvat geometrické vlastnosti? Důvody jsou dva:
-
Za prvé, CSS vlastnosti
width/heightzávisejà na jiné vlastnosti:box-sizing, která definuje, âco jeâ CSS Å¡ÃÅka a výška. ZmÄna vbox-sizingpro úÄely CSS může takový kód v JavaScriptu rozbÃt. -
Za druhé, CSS vlastnosti
width/heightmohou býtauto, napÅÃklad u elementu uvedeného pÅÃmo v HTML kódu:<span id="elem">Ahoj!</span> <script> alert( getComputedStyle(elem).width ); // auto </script>Z pohledu CSS je
width:autozcela v poÅádku, ale v JavaScriptu potÅebujeme pÅesnou velikost vpx, abychom ji mohli použÃt ve výpoÄtech. Zde nám tedy CSS Å¡ÃÅka nenà k niÄemu.
A existuje jeÅ¡tÄ jeden důvod: posuvnÃk. NÄkdy kód, který bez posuvnÃku funguje správnÄ, bude s posuvnÃkem dÄlat chyby, protože posuvnÃk v nÄkterých prohlÞeÄÃch zabÃrá mÃsto z obsahu. SkuteÄná Å¡ÃÅka dostupná pro obsah je tedy menšà než CSS Å¡ÃÅka. Vlastnosti clientWidth/clientHeight to berou v úvahu.
â¦Ale u getComputedStyle(elem).width je situace jiná. NÄkteré prohlÞeÄe (napÅ. Chrome) vracejà skuteÄnou vnitÅnà šÃÅku, od nÞ je odeÄten posuvnÃk, zatÃmco jiné (napÅ. Firefox) vracejà CSS Å¡ÃÅku (a posuvnÃk ignorujÃ). Tyto rozdÃly mezi prohlÞeÄi jsou důvodem, proÄ nepoužÃvat getComputedStyle, ale spolehnout se na geometrické vlastnosti.
Pokud si váš prohlÞeÄ vyhrazuje mÃsto pro posuvnÃk (vÄtÅ¡ina prohlÞeÄů pro Windows to dÄlá), pak si to zde můžete otestovat.
Element s textem má CSS width:300px.
V operaÄnÃm systému Desktop Windows si Firefox, Chrome i Edge rezervujà mÃsto pro posuvnÃk. Ale Firefox zobrazà 300px, zatÃmco Chrome a Edge zobrazà ménÄ. Je to proto, že Firefox vracà CSS Å¡ÃÅku a ostatnà prohlÞeÄe vracejà âskuteÄnouâ Å¡ÃÅku.
ProsÃme vÅ¡imnÄte si, že popsaný rozdÃl má význam jen pÅi naÄÃtánà getComputedStyle(...).width v JavaScriptu, vizuálnÄ je vÅ¡echno v poÅádku.
ShrnutÃ
Elementy obsahujà následujÃcà geometrické vlastnosti:
offsetParentâ je nejbližšà umÃstÄný pÅedek nebotd,th,table,body.offsetLeft/offsetTopâ souÅadnice vzhledem k levému hornÃmu rohu pÅedkaoffsetParent.offsetWidth/offsetHeightâ âvnÄjÅ¡Ãâ Å¡ÃÅka/výška elementu vÄetnÄ ohraniÄenÃ.clientLeft/clientTopâ vzdálenosti od vnÄjÅ¡Ãho levého/hornÃho okraje k vnitÅnÃmu (obsah + vnitÅnà okraje) levému/hornÃmu okraji. V OS Ätených zleva doprava to jsou vždy Å¡ÃÅky levých/hornÃch ohraniÄenÃ. V OS Ätených zprava doleva je svislý posuvnÃk nalevo, protoclientLeftzahrnuje i jeho Å¡ÃÅku.clientWidth/clientHeightâ Å¡ÃÅka/výška obsahu vÄetnÄ vnitÅnÃch okrajů, ale bez posuvnÃku.scrollWidth/scrollHeightâ Å¡ÃÅka/výška obsahu, podobnÄ jakoclientWidth/clientHeight, ale zahrnuje i odrolovanou, neviditelnou Äást elementu.scrollLeft/scrollTopâ Å¡ÃÅka/výška odrolované hornà Äásti elementu od jeho levého hornÃho rohu.
VÅ¡echny vlastnosti jsou pouze pro Ätenà s výjimkou scrollLeft/scrollTop, jejichž zmÄna vyvolá rolovánà elementu.
KomentáÅe
<code>, pro nÄkolik Åádků je obalte znaÄkou<pre>, pro vÃce než 10 Åádků vložte odkaz na pÃskoviÅ¡tÄ (plnkr, jsbin, codepenâ¦)