"Intersection Observer" ger ett sätt att asynkront observera förändringar i skärningspunkten (överlappning) av element. Detta kan vara i förhållande till andra element eller visningsporten. I den här artikeln tar vi en titt på några demos och diskuterar relevansen som Intersection Observer kommer att spela i framtiden för webbutvecklare. Jag delar också kodexempel för att hjälpa dig att komma igång för de sena experimenterna på kvällen. Låt oss dyka in!
De IntersectionObserver
API låter dig registrera en återuppringningsfunktion som exekveras när ett element som övervakas går in i eller lämnar ett annat element eller visningsporten.
Det finns många idéer och förslag som delas i detta W3C explainer doc på GitHub, men Intersection Observer kan vara praktiskt för att bygga in funktioner som:
Kolla in denna demo av Dan Callahan för att klargöra vad vi pratar om:
För att komma igång med IntersectionObserver
låt oss undersöka lämpliga kodningssteg som krävs. Du kan alltid se till att dina avsedda webbläsare / enheter stöder IO API genom att hänvisa till caniuse. Vi börjar med att skapa en observatör och diskutera hur det kan användas för att övervaka komponenter.
IntersectionObserver
börjar med att kräva en grupp av alternativ definierade som ett objekt bokstavligt och passerat som ett argument till ditt definierade observatörsobjekt.
låt alternativ = root: null, // i förhållande till dokumentvyport rootMargin: '0px', // marginal runt rot. Värden liknar css-egenskapen. Enhetslösa värden ej tillåtna tröskelvärde: 1,0 // synlig mängd objekt som visas i förhållande till root; låt observatör = ny IntersectionObserver (återuppringning, alternativ);
Dessa observatörsalternativ på rad 2-4 dikterar några viktiga detaljer när det gäller att upptäcka synligheten hos ett målelement i förhållande till roten. Det första argumentet i observatörsobjektet (sista raden) representerar en återuppringning (funktion) som exekveras när kravet uppfylls av din observatör. Det andra argumentet hänför sig till vårt objekt bokstavligt innehållande observatörens alternativ och accepterar följande egenskaper:
rot
: Det element du vill testa korsningen mot. Ett värde av null
refererar till webbläsarens visningsport. Du kan också vidarebefordra DOM-selektormetoder som document.querySelector (# mytargetobject)
.rootMargin
: Om du behöver expandera eller minska den effektiva storleken på rotelementet innan du beräknar korsningar. Dessa värden passerade liknar CSS marginal
fast egendom. Om rot
elementet anges, värdena kan vara procentandelar.tröskel
: Endera ett enda tal eller en uppsättning tal som anger vilken procentandel av målets synlighet som utlöser observatörens återuppringning. Ett värde på 1,0 betyder att tröskeln inte anses passeras tills varje pixel är synlig, medan 0 betyder att elementet inte syns fullständigt.Som jag tidigare nämnde hanterar du återuppringningsargumentet genom att skapa en funktion som innehåller anpassad logik baserat på projektets behov. Denna logik exekveras när som helst ett observerat element (er) är synligt i förhållande till det definierade rotelementet.
funktion på Ändra (ändringar, observatör) // logik går här låt observatör = ny IntersectionObserver (onChange, alternativ);
Logik inom din observatörs funktion kan vara händelser som laddar bilder, lägger till / tar bort klasser eller kontrollerar synlighet, men valet är ditt om vad som kan göras inifrån, beroende på dina behov och mål.
Varje gång observatören upptäcker en förändring, a förändringar
händelse rapporteras (typ av som a fungera()
rapportera ett händelseobjekt) från observatörsuppringningen. Genom att använda denna utlösande händelse kan vi kontrollera om vårt element är synligt i förhållande till roten innan du kör ytterligare logik genom att detektera egenskaper på Byta
händelse. Vissa utvecklare kommer att ersätta förändringar
med ordet anteckningar
istället, men båda metoderna fungerar på samma sätt.
funktion på Ändra (ändringar, observatör) changes.forEach (change => if (change.intersectionRatio> 0) // din observatörslogik);
Denna slinga anger "För varje ändring som detekteras, kontrollera om målelementet för närvarande är synligt (större än 0) i förhållande till den definierade roten." Korsningsförhållandet hjälper till att rapportera hur mycket av elementet som är synligt med ett värde mellan 0,0 (ej synlig) och 1,0 (fullt synlig). Du kan tänka på korsningsprocent precis som tröskel
egendom definierad i din observatörs alternativ.
Hittills har vi skapat ett alternativobjekt, en återuppringningsfunktion och definierat ett observerobjekt, men vi har fortfarande inget att observera. Det här är där observeringsmetoden kommer att komma i bruk.
låt bilder = document.querySelectorAll ('img'); images.forEach (img => observer.observe (img));
Denna metod lägger till ett element i uppsättningen målelement som ses av IntersectionObserver
. I det här exemplet observerar jag varje bild på sidan med resultaten från bilder
väljare referens. De observera()
Metoden fortsätter att övervaka ett mål tills något av följande inträffar: unobserve ()
eller koppla från()
metoder kallas tillsammans med målelementet eller skärningspunkten raderad. Om du inte längre behöver följa ett element är det bäst att ringa till unobserve ()
och passera i ditt mål som argumentet.
Om du behöver pröva stödet från detta API kan du lägga in allt i en om
/annan
villkorligt uttalande som så:
om ('IntersectionObserver' i fönstret) // supported else // not supported
Eftersom API-gränssnittet fortfarande finns i ett arbetsutkast, uppmanar jag dig att känna igen detektera fönster
objekt, eller du kan också hitta polyfills om du föredrar det.
Följande demo innehåller hela koden jag har diskuterat hittills med några ytterligare tweaks. Den här demonen laddar bilder när de visar 50% av synligheten i förhållande till visningsporten.
Du kanske märker ett annat beteende när det gäller bild
element jämfört med img
element i Chrome och Firefox. Båda webbläsarna laddas bild
element perfekt, men bild
bortse från vår tröskel även med definierade absoluta storlekar. De verkar laddas när de är ungefär 10% i sikte vs. tröskeln på 50% definierad i demo. Lämna en kommentar nedan om du märker denna oddity, eller har haft problem med IntersectionObserver
och bild
specifikt.
Här är en annan demo som skapar ett oändligt rullningsscenario som lata laddar bilder med Ajax för att ladda bilder efter behov.
I detta scenario lägger jag in en sentinel till DOM som mitt observerade mål. Denna sentinel placeras bredvid det sista objektet i den oändliga scroller, och som sentinel kommer tillfälle, laddar återuppringningen data, skapar nästa eller flera objekt, fäster dem till DOM och flyttar sentineln. Om du återvinner ordentligt, skickar du inga ytterligare samtal till observera()
krävs. Här är ett bra diagram av utvecklarteamet i Google för att hjälpa till att visuellt förklara detta tillvägagångssätt.
När en img
element med en begränsning av max bredd: 100%
observeras, kommer det att misslyckas att ladda. Det betyder att alla bilder som laddas på ett lat sätt måste ha begränsningar definierade i CSS eller inline i enlighet därmed Problemet med bild
element som saknar några begränsningar är att det finns noll storlek innan innehållet laddas vilket innebär att de alla korsar visningsporten samtidigt som du bläddrar. jag misstänker getBoundingClientRect ()
är en del av anledningen eftersom detta är en av de främsta metoderna för att erhålla ett elements koordinater och begränsningar.
Använder du IntersectionObserver
i ditt eget arbete just denna minut? Är du upphetsad för den här funktionen och de möjligheter det medför? Skulle kunna IntersectionObserver
ersätt behovet av händelsebaserade funktioner som position: klibbig
? Personligen tycker jag att detta nya API är ett solidt tillägg till våra specifikationer och jag ser fram emot att den fortsätter att växa under de närmaste åren.
Jag har tagit med några användbara länkar nedan och uppmuntrar dig att dyka djupare på fritiden. Varje länk hjälper dig att få en bättre förståelse för hur detta nya API fungerar och fungerar. Om du har några tips eller tricks för andra läsare lämna dem i kommentarerna nedan. Som alltid, glad kodning!