Pozorování pozorovatelů křižovatek

Jak vývoj pro web dospěl a JavaScriptové enginy se zrychlily, jedna oblast zůstává významným úzkým hrdlem – vykreslování. Právě kvůli tomu se tolik nedávných vývojových snah soustředilo na vykreslování, přičemž jedním z nejpopulárnějších příkladů je virtuální DOM. V Dojo 2 bylo prioritou znalost těchto nových API a přístupů. Ale práce s novým API má své problémy a Intersection Observer API se neliší.

Cílem programu Intersection Observers je poskytnout „způsob, jak asynchronně pozorovat změny v průniku cílového prvku s prvkem předchůdce nebo s výřezem dokumentu nejvyšší úrovně“. To webům umožní líně načítat obrázky a další média, vykreslovat a odstraňovat DOM na vyžádání, jak bychom potřebovali pro mřížku s miliony řádků, a poskytovat nekonečné posouvání, jak můžeme vidět ve zdroji sociálních sítí.

Ale Intersection Observers také řeší větší problém, který nám jako vývojářům není hned zřejmý a který je popsán ve vysvětlujícím dokumentu Intersection Observer skupiny Web Incubator Community Group:zobrazování reklam. Interactive Advertising Bureau má zásadu, že reklamy musí být z 50 % viditelné déle než nepřetržitou sekundu. Vzhledem k tomu, že reklamy třetích stran a skripty pro zobrazení stránek jsou notoricky známé tím, že přispívají k nadýmání stránek, zdá se toto API o to důležitější.

Měli bychom se všichni okamžitě pustit do integrace Intersection Observers do našich projektů? Bohužel existuje řada výzev, nesrovnalostí a chyb, kvůli kterým je v současné době mimo dosah a přední implementace polyfillu má řadu nevyřešených problémů. To ale neznamená, že možnost používat Intersection Observers je vzdálená a doufáme, že nastíněním problémů, vytvořením testů a odesláním hlášení o chybách je životaschopné použití jen několik měsíců.

Jak to funguje

Intersection Observery fungují ve dvou částech:instance pozorovatele připojená buď ke konkrétnímu uzlu, nebo k celkovému výřezu a žádost tomuto pozorovateli, aby sledoval konkrétní děti v rámci svých potomků. Když je pozorovatel vytvořen, je také vybaven zpětným voláním, které přijímá jeden nebo více průsečíků.

const observer = new IntersectionObserver((entries) = > { 
    entries.forEach(entry = > console.log(entry.target, entry. intersectionRatio));
  }); 
  observer.observe(node);

Tyto položky jsou srdcem API. Každá z nich má informace popisující změnu křižovatky a uzel, jehož viditelnost se aktuálně mění. Jádrem těchto vstupních objektů jsou tři vlastnosti, z nichž každá poskytuje dimenzi různých informací:

  • isIntersecting udává, zda je uzel přiřazen k target vlastnost je viditelná v kořenovém adresáři pozorovatele
  • intersectionRatio je číslo mezi 0 a 1 udávající poměr pohledu cíle v kořeni pozorovatele
  • intersectionRect je objekt s čísly označujícími velikost, šířku a výšku a polohu nahoře, vlevo, dole a vpravo

Ačkoli je API jednoduché, jeho použití může být složité a jedinečné pro každý případ použití. Několik příkladů je uvedeno ve vysvětlujícím dokumentu Intersection Observer skupiny Web Incubator Community Group.

Problém:Poměr 0

Jednou z nejjednodušších chyb, se kterou se lze setkat, je přechod do poměru 0. Je to problém, protože se to může stát, když se uzel stává viditelným, i když uzel již není viditelný. V níže uvedeném příkladu si při procházení řádků můžete občas všimnout, že se poměr 0 objeví. Pokud ne, posouvejte velmi pomalu, dokud se neobjeví další řádek.

Tento příklad je čtení intersectionRatio vlastnost IntersectionObserverEntry předán zpětnému volání. Zdá se to jako logická vlastnost, kterou lze použít k detekci křižovatky – koneckonců, neznamenal by poměr křižovatek 0, že není vidět? Ale pokud máme kód, který se provede pouze v případě, že tento poměr je nenulový, nikdy se nespustí. Kromě toho, pokud je sledován pouze jeden uzel a přeskočíte-li poměr průniku 0, nespustí se žádné další události a nebudou provedeny žádné aktualizace obsahu.

Řešením je použití isIntersecting vlastnost, která je pravdivá pouze v případě, že tento uzel je nebo se stává viditelným. Bohužel, pokud byl tento kód napsán v TypeScriptu, tato vlastnost v době psaní tohoto článku v rozhraní IntersectionObserverEntry neexistovala, takže by bylo snadné ji přehlédnout.

Upozornění:Obří dítě

Při vytváření nového Observeru křižovatky lze předat řadu možností konfigurace, včetně řady prahových hodnot, které umožňují spuštění vstupu křižovatky a související události podle procenta změny její viditelnosti.

Ve specifikaci W3C se vytvoří průsečík, když "intersectionRatio je větší než poslední položka v observer.thresholds " kde tento poměr je "intersectionArea děleno targetArea ." Když je uzel větší než kořenový uzel, který jej pozoruje, tento poměr se bude neustále zvyšovat, dokud jej podřízený uzel nezaplní, v tomto okamžiku hodnota nikdy nedosáhne 1, ale zůstane celkovým poměrem jejich dvou výšek.

To může být matoucí, pokud očekáváme intersectionRatio neustále zvyšovat mezi 0 a 1, což není cílem API Intersection Observer a nemá žádný logický způsob výpočtu. Ale i když je toto chování dobře pochopeno, je třeba poznamenat, že události se přestanou spouštět, jakmile se tento poměr již nemění. I když intersectionRect.top se stále mění a mohlo by být užitečné pro naše zpětné volání, samotný poměr se nemění.

V tomto demu protokoly konzoly zobrazují průsečíky pro 3 uzly – nad, obří a pod – s velkým počtem prahových hodnot udávajících každou 1% změnu v poměru křižovatek. Věnujte pozornost tomu, kdy „obr“ vyplní rodičovský pohled a přestane vydávat události.

Upozornění:Duplicitní nebo chybějící události

Jakmile bude specifikace jasnější a budou zdokumentovány okrajové případy, budou mezi prohlížeči a polyfill, který by měl být očekáván a spravován. Čtení diskuse v tomto čísle ilustruje některé oblasti ve specifikaci, které stále vyžadují práci, některé oblasti, kde byla specifikace změněna kvůli této diskusi, a dokonce i vysvětlení vývojářů prohlížečů, proč byla rozhodnutí učiněna tak, jak byla.

V tomto příkladu můžeme otevřít konzoli a sledovat události. V době psaní tohoto článku jsme mohli vidět, že Firefox občas vydává dva záznamy, když se uzel stává viditelným. I když se jedná spíše o okrajový případ, ve výše uvedeném problému existují také situace, kdy událost nemusí být vysílána. Dokud nebudou opraveny, zajistěte, aby se vaše implementace nezhroutila, zejména u duplicitních událostí.

Problém:Polyfill

V době psaní tohoto článku polyfill Intersection Observer nesprávně přepisuje nativní implementace IntersectionObserver kvůli neglobální referenci. Předchozí verze nedokázaly aplikovat polyfill tam, kde byla nativní implementace nesprávná, což znamená, že by se měla používat opravená verze, dokud nebude k dispozici nové vydání.

Polyfill se aktuálně spouští pouze při posouvání dokumentu, změně velikosti okna a mutaci DOM s výpočtem zúženého/odskočeného průsečíku po 100 ms. Byl otevřen problém s přidáním událostí animace a přechodu pro pokrytí více typů událostí. Specifikace W3C poznamenává, že nativní detekce průniků „[vyžaduje] mimořádné úsilí vývojáře navzdory jejich širokému použití“, a proto by se mělo očekávat, že 100% pokrytí bude obtížné dosáhnout.

Konečně nastává situace, kdy polyfill nebude hlásit křižovatku. Protože je zcela řízen událostmi, volá .observe na uzlu, který je již v DOM, nepočítá průsečíky. Odeslali jsme problém, který tuto situaci znovu vytváří.

Upozornění:scrollTop

I když toto slovo varování přímo nesouvisí s pozorovateli křižovatky, pravděpodobně způsobí zármutek při použití rolovacího vloženého prvku. Prohlížeče zvolily různé přístupy k tomu, co se stane, když jsou uzly mutovány v rolujícím vloženém prvku.

Přidávání a odebírání uzlů v prohlížeči Chrome automaticky upraví pozici posouvání nadřazeného prvku prostřednictvím scrollTop vlastnictví. Jiné prohlížeče - například Safari - tento výpočet neprovádějí. Z tohoto důvodu budete muset toto omezení obejít ruční úpravou scrollTop na základě změn velikosti uzlů, které se objeví před prvním viditelným řádkem.

Prognóza:Jak se tam dostat

Pokud lze předpokládat, že všichni uživatelé navštěvující bohatou webovou aplikaci budou používat nejnovější verzi předních prohlížečů, existuje dostatek aktivního vývoje a odstraňování chyb, abychom mohli předpokládat, že v blízké budoucnosti budeme mít stabilní API.

Ale protože většina projektů nemůže tento předpoklad učinit, bude muset polyfill v případě potřeby zastoupit. I když také očekáváme, že se tento kód zlepší, existují určitá omezení toho, co lze vypočítat bez přístupu k vykreslovacímu kanálu a nativní smyčce událostí. Použití jednoduchého CSS a znalost podporovaných událostí, které odpovídají vašemu případu použití, by mělo vést k použitelným událostem průniku.

Další informace

SitePen poskytuje vývoj webových aplikací a poradenství podnikovým týmům po celém světě. Spojte se se SitePen ještě dnes a rozšiřte zkušenosti, odbornost a schopnost svého týmu dosáhnout více.