Souřadnice

Abychom mohli prvky pohybovat, měli bychom znát souřadnice.

Většina metod JavaScriptu pracuje s jedním ze dvou souřadnicových systémů:

  1. Vzhledem k oknu – podobně jako position:fixed , počítáno od horního/levého okraje okna.
    • tyto souřadnice označíme jako clientX/clientY , zdůvodnění takového názvu bude jasné později, až budeme studovat vlastnosti události.
  2. Vzhledem k dokumentu – podobně jako position:absolute v kořenovém adresáři dokumentu, počítáno od horního/levého okraje dokumentu.
    • budeme je označovat pageX/pageY .

Když se stránka posune na úplný začátek, takže horní/levý roh okna je přesně horní/levý roh dokumentu, tyto souřadnice se navzájem rovnají. Ale poté, co se dokument posune, souřadnice prvků vůči oknu se změní, jak se prvky budou pohybovat po okně, zatímco souřadnice relativní vůči dokumentu zůstanou stejné.

Na tomto obrázku vezmeme bod v dokumentu a ukážeme jeho souřadnice před rolováním (vlevo) a za ním (vpravo):

Když se dokument posunul:

  • pageY – Souřadnice relativní k dokumentu zůstaly stejné, počítá se od horní části dokumentu (nyní je posunuta ven).
  • clientY – relativní souřadnice okna se změnily (šipka se zkrátila), protože se stejný bod přiblížil k horní části okna.

Souřadnice prvku:getBoundingClientRect

Metoda elem.getBoundingClientRect() vrátí souřadnice okna pro minimální obdélník, který obklopuje elem jako objekt vestavěné třídy DOMRect.

Hlavní DOMRect vlastnosti:

  • x/y – souřadnice X/Y počátku obdélníku vzhledem k oknu,
  • width/height – šířka/výška obdélníku (může být záporná).

Navíc jsou zde odvozené vlastnosti:

  • top/bottom – souřadnice Y pro horní/spodní hranu obdélníku,
  • left/right – Souřadnice X pro levou/pravou hranu obdélníku.

Například kliknutím na toto tlačítko zobrazíte souřadnice jeho okna:

Pokud stránku posouváte a opakujete, všimnete si, že jak se mění poloha tlačítka vzhledem k oknu, jeho souřadnice okna (y/top/bottom pokud rolujete svisle) změňte také.

Zde je obrázek elem.getBoundingClientRect() výstup:

Jak vidíte, x/y a width/height plně popsat obdélník. Z nich lze snadno vypočítat odvozené vlastnosti:

  • left = x
  • top = y
  • right = x + width
  • bottom = y + height

Poznámka:

  • Souřadnice mohou být desetinné zlomky, například 10.5 . To je normální, prohlížeč interně používá ve výpočtech zlomky. Při nastavení na style.left/top je nemusíme zaokrouhlovat .
  • Souřadnice mohou být záporné. Pokud je například stránka rolována tak, že elem je nyní nad oknem a poté elem.getBoundingClientRect().top je negativní.
Proč jsou potřebné odvozené vlastnosti? Proč top/left existovat, pokud existuje x/y ?

Matematicky je obdélník jednoznačně definován svým počátečním bodem (x,y) a směrový vektor (width,height) . Další odvozené vlastnosti jsou tedy pro pohodlí.

Technicky je to možné pro width/height být negativní, což umožňuje „směrovaný“ obdélník, např. reprezentovat výběr myší s řádně označeným začátkem a koncem.

Negativní width/height hodnoty znamenají, že obdélník začíná v pravém dolním rohu a poté „roste“ doleva nahoru.

Zde je obdélník se záporným číslem width a height (např. width=-200 , height=-100 ):

Jak můžete vidět, left/top nerovná se x/y v takovém případě.

V praxi však elem.getBoundingClientRect() vždy vrací kladnou šířku/výšku, zde zmiňujeme zápornou hodnotu width/height jen abyste pochopili, proč tyto zdánlivě duplicitní vlastnosti nejsou ve skutečnosti duplikáty.

Internet Explorer:žádná podpora pro x/y

Internet Explorer nepodporuje x/y vlastnosti z historických důvodů.

Můžeme tedy buď vytvořit polyfill (přidat getry v DomRect.prototype ) nebo stačí použít top/left , protože jsou vždy stejné jako x/y pro kladných width/height , zejména ve výsledku elem.getBoundingClientRect() .

Souřadnice vpravo/dole se liší od vlastností pozice CSS

Mezi souřadnicemi relativními k oknu a CSS position:fixed jsou zřejmé podobnosti .

Ale v umístění CSS right vlastnost znamená vzdálenost od pravého okraje a bottom vlastnost znamená vzdálenost od spodního okraje.

Pokud se jen podíváme na obrázek výše, vidíme, že v JavaScriptu tomu tak není. Všechny souřadnice okna se počítají od levého horního rohu, včetně těchto.

elementFromPoint(x, y)

Volání na document.elementFromPoint(x, y) vrátí nejvíce vnořený prvek na souřadnicích okna (x, y) .

Syntaxe je:

let elem = document.elementFromPoint(x, y);

Například níže uvedený kód zvýrazní a zobrazí značku prvku, který je nyní uprostřed okna:

let centerX = document.documentElement.clientWidth / 2;
let centerY = document.documentElement.clientHeight / 2;

let elem = document.elementFromPoint(centerX, centerY);

elem.style.background = "red";
alert(elem.tagName);

Protože používá souřadnice okna, prvek se může lišit v závislosti na aktuální pozici posouvání.

Pro souřadnice mimo okno elementFromPoint vrátí null

Metoda document.elementFromPoint(x,y) funguje pouze pokud (x,y) jsou uvnitř viditelné oblasti.

Pokud je některá ze souřadnic záporná nebo přesahuje šířku/výšku okna, vrátí null .

Zde je typická chyba, ke které může dojít, pokud ji nezkontrolujeme:

let elem = document.elementFromPoint(x, y);
// if the coordinates happen to be out of the window, then elem = null
elem.style.background = ''; // Error!

Použití pro „pevné“ umístění

Většinu času potřebujeme souřadnice, abychom něco umístili.

Chcete-li zobrazit něco poblíž prvku, můžeme použít getBoundingClientRect získat jeho souřadnice a poté CSS position spolu s left/top (nebo right/bottom ).

Například funkce createMessageUnder(elem, html) níže zobrazuje zprávu pod elem :

let elem = document.getElementById("coords-show-mark");

function createMessageUnder(elem, html) {
 // create message element
 let message = document.createElement('div');
 // better to use a css class for the style here
 message.style.cssText = "position:fixed; color: red";

 // assign coordinates, don't forget "px"!
 let coords = elem.getBoundingClientRect();

 message.style.left = coords.left + "px";
 message.style.top = coords.bottom + "px";

 message.innerHTML = html;

 return message;
}

// Usage:
// add it for 5 seconds in the document
let message = createMessageUnder(elem, 'Hello, world!');
document.body.append(message);
setTimeout(() => message.remove(), 5000);

Klepnutím na tlačítko jej spustíte:

Kód lze upravit tak, aby zobrazoval zprávu vlevo, vpravo, níže, aplikoval animace CSS pro „roztmívání“ a tak dále. To je snadné, protože máme všechny souřadnice a velikosti prvku.

Všimněte si však důležitého detailu:když se stránka posune, zpráva od tlačítka odteče.

Důvod je zřejmý:prvek zprávy spoléhá na position:fixed , takže zůstane na stejném místě okna, zatímco se stránka posune pryč.

Abychom to změnili, musíme použít souřadnice založené na dokumentu a position:absolute .

Souřadnice dokumentu

Souřadnice relativní k dokumentu začínají v levém horním rohu dokumentu, nikoli v okně.

V CSS odpovídají souřadnice okna position:fixed , zatímco souřadnice dokumentu jsou podobné position:absolute nahoře.

Můžeme použít position:absolute a top/left umístit něco na určité místo dokumentu tak, aby to tam zůstalo během posouvání stránky. Ale nejprve potřebujeme správné souřadnice.

Neexistuje žádná standardní metoda, jak získat souřadnice dokumentu prvku. Ale je snadné to napsat.

Tyto dva souřadnicové systémy jsou spojeny vzorcem:

  • pageY =clientY + výška odrolované svislé části dokumentu.
  • pageX =clientX + šířka odrolované vodorovné části dokumentu.

Funkce getCoords(elem) převezme souřadnice okna z elem.getBoundingClientRect() a přidejte k nim aktuální svitek:

// get document coordinates of the element
function getCoords(elem) {
 let box = elem.getBoundingClientRect();

 return {
 top: box.top + window.pageYOffset,
 right: box.right + window.pageXOffset,
 bottom: box.bottom + window.pageYOffset,
 left: box.left + window.pageXOffset
 };
}

Pokud jsme jej ve výše uvedeném příkladu použili s position:absolute , pak by zpráva zůstala poblíž prvku při posouvání.

Upravený createMessageUnder funkce:

function createMessageUnder(elem, html) {
 let message = document.createElement('div');
 message.style.cssText = "position:absolute; color: red";

 let coords = getCoords(elem);

 message.style.left = coords.left + "px";
 message.style.top = coords.bottom + "px";

 message.innerHTML = html;

 return message;
}

Shrnutí

Jakýkoli bod na stránce má souřadnice:

  1. Vzhledem k oknu – elem.getBoundingClientRect() .
  2. Vzhledem k dokumentu – elem.getBoundingClientRect() plus posunutí aktuální stránky.

Souřadnice okna jsou skvělé pro použití s ​​position:fixed a souřadnice dokumentu fungují dobře s position:absolute .

Oba souřadnicové systémy mají svá pro a proti; jsou chvíle, kdy potřebujeme jedno nebo druhé, stejně jako CSS position absolute a fixed .