Existuje mnoho vlastností JavaScriptu, které nám umožňují číst informace o šířce, výšce a dalších geometrických funkcích.
Často je potřebujeme při přesouvání nebo umisťování prvků v JavaScriptu.
Ukázkový prvek
Jako ukázkový prvek k demonstraci vlastností použijeme prvek uvedený níže:
<div id="example">
...Text...
</div>
<style>
#example {
width: 300px;
height: 200px;
border: 25px solid #E8C48F;
padding: 20px;
overflow: auto;
}
</style>
Má ohraničení, výplň a rolování. Kompletní sada funkcí. Nejsou zde žádné okraje, protože nejsou součástí samotného prvku a neexistují pro ně žádné speciální vlastnosti.
Prvek vypadá takto:
Dokument můžete otevřít v karanténě.
Pozor na posuvníkObrázek výše ukazuje nejsložitější případ, kdy má prvek posuvník. Některé prohlížeče (ne všechny) si pro něj rezervují místo tím, že jej převezmou z obsahu (výše označeného jako „šířka obsahu“).
Takže bez posuvníku by šířka obsahu byla 300px
, ale pokud je posuvník 16px
široký (šířka se může mezi zařízeními a prohlížeči lišit), pak pouze 300 - 16 = 284px
zůstává a měli bychom to vzít v úvahu. Proto příklady z této kapitoly předpokládají, že existuje posuvník. Bez něj jsou některé výpočty jednodušší.
padding-bottom
oblast může být vyplněna textem
Výplně jsou na našich ilustracích obvykle zobrazeny prázdné, ale pokud je v prvku mnoho textu a přetéká, prohlížeče zobrazí „přetékající“ text na padding-bottom
, to je normální.
Geometrie
Zde je celkový obrázek s vlastnostmi geometrie:
Hodnoty těchto vlastností jsou technicky čísla, ale tato čísla jsou „pixelů“, takže se jedná o měření pixelů.
Začněme zkoumat vlastnosti počínaje vnějškem prvku.
offsetParent, offsetLeft/Top
Tyto vlastnosti jsou potřeba jen zřídka, ale přesto jsou to „nejvnější“ vlastnosti geometrie, takže začneme s nimi.
offsetParent
je nejbližší předek, kterého prohlížeč používá pro výpočet souřadnic během vykreslování.
To je nejbližší předek, který je jedním z následujících:
- Umístění CSS (
position
jeabsolute
,relative
,fixed
nebosticky
), nebo <td>
,<th>
nebo<table>
nebo<body>
.
Vlastnosti offsetLeft/offsetTop
zadejte souřadnice x/y vzhledem k offsetParent
levém horním rohu.
V níže uvedeném příkladu vnitřní <div>
má <main>
jako offsetParent
a offsetLeft/offsetTop
posune z levého horního rohu (180
):
<main style="position: relative" id="main">
<article>
<div id="example" style="position: absolute; left: 180px; top: 180px">...</div>
</article>
</main>
<script>
alert(example.offsetParent.id); // main
alert(example.offsetLeft); // 180 (note: a number, not a string "180px")
alert(example.offsetTop); // 180
</script>
Existuje několik případů, kdy offsetParent
je null
:
- Pro nezobrazené prvky (
display:none
nebo není v dokumentu). - Pro
<body>
a<html>
. - Pro prvky s
position:fixed
.
offsetWidth/Height
Nyní přejdeme k samotnému prvku.
Tyto dvě vlastnosti jsou nejjednodušší. Poskytují „vnější“ šířku/výšku prvku. Nebo jinými slovy, jeho plná velikost včetně okrajů.
Pro náš ukázkový prvek:
offsetWidth = 390
– vnější šířku lze vypočítat jako vnitřní šířku CSS (300px
) plus výplně (2 * 20px
) a ohraničení (2 * 25px
).offsetHeight = 290
– vnější výška.
Vlastnosti geometrie se počítají pouze pro zobrazené prvky.
Pokud má prvek (nebo kterýkoli z jeho předků) display:none
nebo není v dokumentu, pak jsou všechny vlastnosti geometrie nulové (nebo null
pro offsetParent
).
Například offsetParent
je null
a offsetWidth
, offsetHeight
jsou 0
když jsme vytvořili prvek, ale ještě jsme ho nevložili do dokumentu, nebo má (nebo jeho předchůdce) display:none
.
Můžeme to použít ke kontrole, zda je prvek skrytý, takto:
function isHidden(elem) {
return !elem.offsetWidth && !elem.offsetHeight;
}
Vezměte prosím na vědomí, že takový isHidden
vrátí true
pro prvky, které jsou na obrazovce, ale mají nulovou velikost.
klient nahoře/vlevo
Uvnitř prvku máme ohraničení.
K jejich měření existují vlastnosti clientTop
a clientLeft
.
V našem příkladu:
clientLeft = 25
– šířka levého okrajeclientTop = 25
– šířka horního okraje
…Ale abych byl přesný – tyto vlastnosti nejsou šířka/výška okraje, ale relativní souřadnice vnitřní strany od vnější strany.
Jaký je rozdíl?
Zviditelní se, když je dokument zprava doleva (operační systém je v arabštině nebo hebrejštině). Posuvník pak není vpravo, ale vlevo a pak clientLeft
zahrnuje také šířku posuvníku.
V takovém případě clientLeft
nebude 25
, ale s šířkou posuvníku 25 + 16 = 41
.
Zde je příklad v hebrejštině:
šířka/výška klienta
Tyto vlastnosti poskytují velikost oblasti uvnitř hranic prvku.
Zahrnují šířku obsahu spolu s odsazením, ale bez posuvníku:
Na obrázku výše nejprve uvažujme clientHeight
.
Neexistuje žádný vodorovný posuvník, takže je to přesně součet toho, co je uvnitř ohraničení:CSS-height 200px
plus horní a spodní vycpávky (2 * 20px
) celkem 240px
.
Nyní clientWidth
– zde není šířka obsahu 300px
, ale 284px
, protože 16px
jsou obsazeny posuvníkem. Součet je tedy 284px
plus levé a pravé vycpávky, celkem 324px
.
Pokud nejsou žádné výplně, pak clientWidth/Height
je přesně oblast obsahu, uvnitř ohraničení a posuvníku (pokud existuje).
Takže když neexistuje žádná výplň, můžeme použít clientWidth/clientHeight
získat velikost oblasti obsahu.
šířka/výška posuvníku
Tyto vlastnosti jsou jako clientWidth/clientHeight
, ale zahrnují také odrolované (skryté) části:
Na obrázku výše:
scrollHeight = 723
– je plná vnitřní výška oblasti obsahu včetně vysunutých částí.scrollWidth = 324
– je plná vnitřní šířka, zde nemáme žádné vodorovné posouvání, takže se rovnáclientWidth
.
Tyto vlastnosti můžeme použít k rozšíření prvku do šířky na jeho plnou šířku/výšku.
Takhle:
// expand the element to the full content height
element.style.height = `${element.scrollHeight}px`;
Kliknutím na tlačítko prvek rozbalíte:
text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
scrollLeft/scrollTop
Vlastnosti scrollLeft/scrollTop
jsou šířka/výška skryté, vysunuté části prvku.
Na obrázku níže vidíme scrollHeight
a scrollTop
pro blok se svislým posouváním.
Jinými slovy scrollTop
je „o kolik je posunuto nahoru“.
scrollLeft/scrollTop
lze upravit
Většina vlastností geometrie zde je pouze pro čtení, ale scrollLeft/scrollTop
lze změnit a prohlížeč bude prvek posouvat.
Pokud kliknete na prvek níže, kód elem.scrollTop += 10
provádí. Tím se obsah prvku posune na 10px
dolů.
Mě
1
2
3
4
5
6
7
8
9
Nastavení scrollTop
na 0
nebo velkou hodnotu, například 1e9
způsobí, že se prvek posune úplně nahoru/dolů.
Neberte šířku/výšku z CSS
Právě jsme probrali geometrické vlastnosti prvků DOM, které lze použít k získání šířky, výšky a výpočtu vzdáleností.
Ale jak víme z kapitoly Styly a třídy, CSS-height and width můžeme číst pomocí getComputedStyle
.
Proč tedy nečíst šířku prvku pomocí getComputedStyle
, takhle?
let elem = document.body;
alert( getComputedStyle(elem).width ); // show CSS width for elem
Proč bychom místo toho měli používat vlastnosti geometrie? Existují dva důvody:
-
Nejprve CSS
width/height
závisí na jiné vlastnosti:box-sizing
který definuje šířku a výšku CSS „co je“. Změna vbox-sizing
pro účely CSS může takový JavaScript porušit. -
Za druhé, CSS
width/height
může býtauto
, například pro vložený prvek:<span id="elem">Hello!</span> <script> alert( getComputedStyle(elem).width ); // auto </script>
Z hlediska CSS
width:auto
je naprosto normální, ale v JavaScriptu potřebujeme přesnou velikost vpx
které můžeme použít při výpočtech. Takže zde je šířka CSS k ničemu.
A je tu ještě jeden důvod:posuvník. Někdy se kód, který funguje bez posuvníku, stává chybným, protože posuvník v některých prohlížečích zabírá místo obsahu. Skutečná šířka dostupná pro obsah je tedy menší než šířka CSS. A clientWidth/clientHeight
vzít to v úvahu.
…Ale s getComputedStyle(elem).width
situace je jiná. Některé prohlížeče (např. Chrome) vracejí skutečnou vnitřní šířku mínus posuvník a některé z nich (např. Firefox) – šířku CSS (posuvník ignorují). Takové rozdíly mezi prohlížeči jsou důvodem, proč nepoužívat getComputedStyle
, ale spíše spoléhat na vlastnosti geometrie.
Pokud si váš prohlížeč vyhrazuje místo pro posuvník (většina prohlížečů pro Windows ho má), můžete jej otestovat níže.
Prvek s textem má CSS width:300px
.
Na stolním operačním systému Windows, Firefox, Chrome, Edge všechny rezervují prostor pro posuvník. Firefox ale zobrazuje 300px
, zatímco Chrome a Edge zobrazují méně. Je to proto, že Firefox vrací šířku CSS a ostatní prohlížeče vrací „skutečnou“ šířku.
Upozorňujeme, že popsaný rozdíl se týká pouze čtení getComputedStyle(...).width
z JavaScriptu, vizuálně je vše v pořádku.
Shrnutí
Prvky mají následující vlastnosti geometrie:
offsetParent
– je nejbližší umístěný předek nebotd
,th
,table
,body
.offsetLeft/offsetTop
– souřadnice vzhledem k levému hornímu okrajioffsetParent
.offsetWidth/offsetHeight
– „vnější“ šířka/výška prvku včetně ohraničení.clientLeft/clientTop
– vzdálenosti od levého horního vnějšího rohu k levému hornímu vnitřnímu rohu (obsah + výplň). U OS zleva doprava jsou to vždy šířky levého/horního okraje. U OS se zprava doleva je svislý posuvník vlevo, takžeclientLeft
zahrnuje i jeho šířku.clientWidth/clientHeight
– šířka/výška obsahu včetně odsazení, ale bez posuvníku.scrollWidth/scrollHeight
– šířka/výška obsahu, stejně jakoclientWidth/clientHeight
, ale také zahrnují odrolovanou, neviditelnou část prvku.scrollLeft/scrollTop
– šířka/výška odsunuté horní části prvku, počínaje jeho levým horním rohem.
Všechny vlastnosti jsou pouze pro čtení kromě scrollLeft/scrollTop
které při změně posouvají prvek v prohlížeči.