Velikost oken a posouvání

Jak zjistíme šířku a výšku okna prohlížeče? Jak získáme plnou šířku a výšku dokumentu, včetně odrolované části? Jak rolujeme stránku pomocí JavaScriptu?

Pro tento typ informací můžeme použít kořenový prvek dokumentu document.documentElement , což odpovídá <html> štítek. Existují však další metody a zvláštnosti, které je třeba zvážit.

Šířka/výška okna

K získání šířky a výšky okna můžeme použít clientWidth/clientHeight z document.documentElement :

Toto tlačítko například zobrazuje výšku vašeho okna:

Ne window.innerWidth/innerHeight

Prohlížeče také podporují vlastnosti jako window.innerWidth/innerHeight . Vypadají jako to, co chceme, tak proč je místo toho nepoužít?

Pokud existuje posuvník a zabírá nějaké místo, clientWidth/clientHeight zadejte šířku/výšku bez ní (odečtěte ji). Jinými slovy, vrátí šířku/výšku viditelné části dokumentu, která je k dispozici pro obsah.

window.innerWidth/innerHeight obsahuje posuvník.

Pokud je zde posuvník a zabírá nějaké místo, pak tyto dva řádky zobrazují různé hodnoty:

alert( window.innerWidth ); // full window width
alert( document.documentElement.clientWidth ); // window width minus the scrollbar

Ve většině případů potřebujeme dostupné šířku okna, abychom něco nakreslili nebo umístili do posuvníků (pokud nějaké existují), takže bychom měli použít documentElement.clientHeight/clientWidth .

DOCTYPE je důležité

Poznámka:Vlastnosti geometrie nejvyšší úrovně mohou fungovat trochu jinak, když není k dispozici <!DOCTYPE HTML> v HTML. Podivné věci jsou možné.

V moderním HTML bychom měli vždy psát DOCTYPE .

Šířka/výška dokumentu

Teoreticky, jako kořenový prvek dokumentu je document.documentElement a obsahuje veškerý obsah, mohli bychom změřit plnou velikost dokumentu jako document.documentElement.scrollWidth/scrollHeight .

Ale na tomto prvku pro celou stránku tyto vlastnosti nefungují tak, jak bylo zamýšleno. Pokud v prohlížeči Chrome/Safari/Opera není žádné posouvání, pak documentElement.scrollHeight může být dokonce menší než documentElement.clientHeight ! Divné, že?

Abychom spolehlivě získali plnou výšku dokumentu, měli bychom vzít maximum z těchto vlastností:

let scrollHeight = Math.max(
 document.body.scrollHeight, document.documentElement.scrollHeight,
 document.body.offsetHeight, document.documentElement.offsetHeight,
 document.body.clientHeight, document.documentElement.clientHeight
);

alert('Full document height, with scrolled out part: ' + scrollHeight);

Proč? Raději se neptejte. Tyto nekonzistence pocházejí z dávných dob, nikoli z „chytré“ logiky.

Získat aktuální svitek

Prvky DOM mají aktuální stav posouvání ve svých scrollLeft/scrollTop vlastnosti.

Pro posouvání dokumentu document.documentElement.scrollLeft/scrollTop funguje ve většině prohlížečů, kromě starších založených na WebKitu, jako je Safari (chyba 5991), kde bychom měli používat document.body místo document.documentElement .

Naštěstí si tyto zvláštnosti nemusíme vůbec pamatovat, protože svitek je dostupný ve speciálních vlastnostech window.pageXOffset/pageYOffset :

alert('Current scroll from the top: ' + window.pageYOffset);
alert('Current scroll from the left: ' + window.pageXOffset);

Tyto vlastnosti jsou pouze pro čtení.

K dispozici také jako window vlastnosti scrollX a scrollY

Z historických důvodů existují obě vlastnosti, ale jsou stejné:

  • window.pageXOffset je alias window.scrollX .
  • window.pageYOffset je alias window.scrollY .

Posouvání:scrollTo, scrollBy, scrollIntoView

Důležité:

Chcete-li stránku posouvat pomocí JavaScriptu, musí být její DOM plně vytvořen.

Pokud se například pokusíme posouvat stránku pomocí skriptu v <head> , nebude to fungovat.

Běžné prvky lze posouvat změnou scrollTop/scrollLeft .

Totéž můžeme udělat pro stránku pomocí document.documentElement.scrollTop/scrollLeft (kromě Safari, kde document.body.scrollTop/Left by měl být použit místo toho).

Případně existuje jednodušší, univerzální řešení:speciální metody window.scrollBy(x,y) a window.scrollTo(pageX,pageY).

  • Metoda scrollBy(x,y) posouvá stránku vzhledem k její aktuální pozici . Například scrollBy(0,10) posouvá stránku 10px dolů.

    Níže uvedené tlačítko to ukazuje:

  • Metoda scrollTo(pageX,pageY) posune stránku na absolutní souřadnice , takže levý horní roh viditelné části má souřadnice (pageX, pageY) vzhledem k levému hornímu rohu dokumentu. Je to jako nastavení scrollLeft/scrollTop .

    Pro posun na úplný začátek můžeme použít scrollTo(0,0) .

Tyto metody fungují pro všechny prohlížeče stejně.

scrollIntoView

Pro úplnost uveďme ještě jednu metodu:elem.scrollIntoView(top).

Volání na elem.scrollIntoView(top) posouvá stránku na elem viditelné. Má to jeden argument:

  • Pokud top=true (to je výchozí nastavení), pak se stránka posune na elem se zobrazí v horní části okna. Horní okraj prvku bude zarovnán s horní částí okna.
  • Pokud top=false , pak se stránka posune a vytvoří elem se objeví ve spodní části. Spodní okraj prvku bude zarovnán se spodní částí okna.

Tlačítko níže posouvá stránku tak, aby byla umístěna v horní části okna:

A toto tlačítko posouvá stránku tak, aby se umístila dole:

Zakažte posouvání

Někdy potřebujeme dokument „nerolovat“. Například, když potřebujeme zakrýt stránku velkým sdělením vyžadujícím okamžitou pozornost a chceme, aby návštěvník interagoval s tímto sdělením, nikoli s dokumentem.

Aby bylo možné dokument neposouvat, stačí nastavit document.body.style.overflow = "hidden" . Stránka „zamrzne“ ve své aktuální pozici posouvání.

Zkuste to:

První tlačítko zmrazí rolování, zatímco druhé jej uvolní.

Stejnou techniku ​​můžeme použít k zmrazení posouvání pro další prvky, nejen pro document.body .

Nevýhodou metody je, že zmizí posuvník. Pokud zabíralo nějaké místo, pak je toto místo nyní volné a obsah „skáče“, aby jej zaplnil.

Vypadá to trochu divně, ale dá se to obejít, když porovnáme clientWidth před a po zmrazení. Pokud se zvýšila (zmizel posuvník), přidejte padding na document.body místo posuvníku, aby byla šířka obsahu stejná.

Shrnutí

Geometrie:

  • Šířka/výška viditelné části dokumentu (šířka/výška oblasti obsahu):document.documentElement.clientWidth/clientHeight

  • Šířka/výška celého dokumentu s vysunutou částí:

    let scrollHeight = Math.max(
     document.body.scrollHeight, document.documentElement.scrollHeight,
     document.body.offsetHeight, document.documentElement.offsetHeight,
     document.body.clientHeight, document.documentElement.clientHeight
    );

Posouvání:

  • Přečtěte si aktuální svitek:window.pageYOffset/pageXOffset .

  • Změna aktuálního posouvání:

    • window.scrollTo(pageX,pageY) – absolutní souřadnice,
    • window.scrollBy(x,y) – rolování vzhledem k aktuálnímu místu,
    • elem.scrollIntoView(top) – přejděte na elem viditelné (zarovnat s horní/spodní částí okna).