Intersecție Observer Elemente de urmărire derulând în Vizualizare

"Observatorul de intersecție" oferă o modalitate de observare asincronă a schimbărilor în intersecția (suprapunerea) elementelor. Acest lucru poate fi în legătură cu alte elemente sau cu fereastra de vizualizare. În acest articol vom examina câteva demo-uri și vom discuta despre relevanța pe care Intersection Observer o va juca în viitor pentru dezvoltatorii web. Voi împărtăși, de asemenea, exemple de cod pentru a vă ajuta să începeți pentru sesiunile de experimentare cu noaptea târzie. Hai să ne aruncăm!

Ce poate face observatorul de intersecție?

IntersectionObserver API vă permite să înregistrați o funcție de apel invers care este executată ori de câte ori un element care este monitorizat intră sau iese dintr-un alt element sau portul de vizualizare. 

Există o mulțime de idei și sugestii împărtășite în acest document explicativ W3C de la GitHub, cu toate acestea, Intersection Observer poate fi util pentru construirea nativă a unor caracteristici precum:

  • Lazy Loading
  • Infinite Scrolling
  • Raportarea vizibilității / locației
  • Executarea animațiilor

Verificați acest demo de Dan Callahan pentru a clarifica despre ce vorbim:

Pentru a începe cu IntersectionObserver să explorăm pașii corespunzători de codificare necesari. Puteți să vă asigurați întotdeauna că browserele / dispozitivele intenționate acceptă API-ul IO prin referire la caniuse. Vom începe prin crearea unui observator și discutarea modului în care acesta poate fi utilizat pentru a monitoriza componentele.

Crearea unui observator

 IntersectionObserver începe prin a solicita un grup de opțiuni definite ca un obiect literal și trecut ca un argument pentru obiectul dvs. de observație definit.

permiteți opțiunile = root: null, // relativ la documentul de vizualizare a documentului rootMargin: '0px', // marginea în jurul rădăcină. Valorile sunt similare cu proprietatea css. Valori unice de valoare nu sunt permise: 1.0 // cantitatea vizibilă a elementului afișată în raport cu rădăcina; permiteți observer = nou IntersectionObserver (callback, opțiuni);

Aceste opțiuni de observație de pe liniile 2-4 vor dicta câteva detalii importante în ceea ce privește detectarea vizibilității unui element țintă în raport cu rădăcina. Primul argument al obiectului observatorului (ultima linie) reprezintă o funcție de returnare (funcție) care este executată deoarece cerințele sunt îndeplinite de către observator. Al doilea argument se referă la obiectul nostru literal care conține opțiunile observatorului și acceptă următoarele proprietăți:

  • rădăcină: Elementul pe care doriți să îl testați împotriva intersecției. O valoare de nul se referă la portul de vizualizare al browserului. De asemenea, puteți trece în metodele de selectare DOM, cum ar fi document.querySelector ( '# mytargetobject').
  • rootMargin: Dacă aveți nevoie să extindeți sau să micșorați mărimea efectivă a elementului rădăcină înainte de a calcula intersecțiile. Aceste valori sunt similare cu cele ale CSS margine proprietate. În cazul în care rădăcină elementul este specificat, valorile pot fi procente.
  • prag: Fie un singur număr, fie o serie de numere care indică procentul vizibilității țintă declanșează apelul observatorului. O valoare de 1,0 înseamnă că pragul nu este considerat trecut până când fiecare pixel este vizibil, în timp ce 0 înseamnă că elementul este complet vizualizat.

După cum am menționat anterior, veți gestiona argumentul de apel invers prin crearea unei funcții care conține logica personalizată pe baza nevoilor proiectului dvs. Această logică este executată oricând un element (ele) observat este vizibil în raport cu elementul rădăcină definit.

functie peChange (modificari, observator) // logica merge aici let observer = new IntersectionObserver (onChange, options);

Logica în cadrul funcției de observator poate fi evenimente cum ar fi încărcarea imaginilor, adăugarea / eliminarea clasei sau controlul vizibilității, dar alegerea dvs. este a ceea ce se poate face din interior în funcție de nevoile și obiectivele dvs..

De fiecare dată când observatorul detectează o schimbare, a schimbări eveniment este raportat (un fel de a funcţie() raportarea unui obiect de evenimente) din apelul invers al observatorului. Prin utilizarea acestui eveniment declanșat, putem verifica pentru vizibilitatea elementului nostru în raport cu radacina înainte de a rula orice logică suplimentară prin detectarea proprietăților pe Schimbare eveniment. Unii dezvoltatori vor înlocui schimbări cu cuvântul intrări în schimb, ambele abordări funcționează la fel.

funcția peChange (modificări, observator) changes.forEach (schimbare => if (change.intersectionRatio> 0) // logica observatorului); 

Această buclă afișează "Pentru fiecare schimbare detectată, verificați dacă elementul țintă este în prezent vizibil (mai mare de 0) în raport cu rădăcina definită". Raportul de intersecție ajută la raportarea cantității elementului vizibil utilizând o valoare între 0,0 (nu este vizibil) și 1,0 (pe deplin vizibil). Vă puteți gândi la raportul de intersecție la fel ca și prag proprietate definită în opțiunile observatorului.

Metoda de observare

Până acum, am creat un obiect de opțiuni, o funcție de apel invers și am definit un obiect observator, dar încă nu avem nimic de observat. Acesta este locul în care metoda de observare va intra în serviciu.

permiteți imagini = document.querySelectorAll ('img'); images.forEach (img => observer.observe (img));

Această metodă adaugă un element setului de elemente vizate fiind urmărit de către IntersectionObserver. În acest exemplu, observ fiecare imagine pe pagină cu rezultatele obținute de la imagini selector de referință. observa() metoda va continua să monitorizeze o țintă până la oricare dintre următoarele: unobserve () sau deconecta() metodele sunt numite împreună cu elementul țintă sau rădăcina de intersecție șterse. Dacă nu mai trebuie să observați un element, este mai bine să faceți un apel unobserve () și treceți în țintă ca argument.

Condiții de asistență

Dacă aveți nevoie să încercați suportul acestui API, puteți împacheta totul într-un dacă/altfel declarație condiționată așa cum este:

dacă ("IntersectionObserver" în fereastră) // suportată altceva // nu este suportată

Deoarece API-ul Intersection Observer se află încă într-o etapă de lucru, vă încurajez să identificați fereastră obiect, sau puteți găsi, de asemenea, polyfills, dacă preferați.

Exemple live

Următoarea demonstrație conține tot codul pe care l-am discutat până acum cu câteva îmbunătățiri suplimentare. Acest demo leneș încarcă imagini atunci când își afișează 50% din vizibilitatea lor în raport cu portul de vizualizare.

S-ar putea să observați un comportament diferit atunci când este vorba despre imagine elemente în comparație cu img elemente în Chrome și Firefox. Ambele browsere se încarcă imagine elementele perfect, dar imagine ignoră pragul nostru chiar și cu constrângeri de dimensiune absolută definite. Se pare că se încarcă atunci când sunt în jur de 10% din vedere față de pragul de 50% definit în demo. Lăsați un comentariu mai jos dacă observați această ciudățenie sau aveți probleme cu dvs. IntersectionObserver și imagine specific.

Iată o altă demonstrație care creează un scenariu infinit de defilare care lenează imaginile folosind Ajax pentru a încărca imaginile după cum este necesar.

În acest scenariu, introduc un santinel la DOM ca țintă observată. Acest santinel este plasat lângă ultimul element din scrollerul infinit și, pe măsură ce santinelul intră în vedere, callback-ul încarcă datele, creează elementele următoare, le atașează DOM și repoziționează santinelul. Dacă reciclați în mod adecvat santinelul, nu vi se solicită niciun apel suplimentar observa() sunt necesare. Iată o diagramă excelentă de către echipa Google Developer pentru a ajuta la explicarea vizuală a acestei abordări.

O notă privind imaginile

Când o img element cu o constrângere de max-lățime: 100% se observă că nu se va încărca. Asta înseamnă că orice imagine încărcată într-un mod leneș trebuie să aibă constrângeri definite în CSS sau inline în consecință imagine elementele care nu au nici un fel de constrângeri sunt că există o dimensiune zero înainte ca conținutul lor să fie încărcat; ceea ce înseamnă că toate intersectează vizualizarea simultan în timp ce defilați. suspectez getBoundingClientRect () face parte din motiv deoarece aceasta este una dintre metodele primare pentru a obține coordonatele și constrângerile elementului.

Concluzie

Folosesti IntersectionObserver în dreptul tău de muncă în acest moment? Ești încântat de această caracteristică și de posibilitățile pe care le aduce? Ar putea IntersectionObserver înlocuiți nevoia de caracteristici bazate pe evenimente cum ar fi pozitie: lipicios? Personal, consider că acest API nou este un plus solid față de specificațiile noastre și cu nerăbdare aștept cu nerăbdare să-și continue creșterea în următorii ani. 

Am inclus câteva linkuri utile de mai jos și vă încurajez să vă scufundați mai adânc în timpul liber. Fiecare legătură vă va ajuta să înțelegeți mai bine cum funcționează și funcționează acest API nou. Dacă aveți sfaturi sau trucuri pentru alți cititori, lăsați-i în comentariile de mai jos. Ca întotdeauna, codificare fericită!

Link-uri

  • LazyLoad (vanilla-lazyload)
  • Intersecție Observer Exemple
  • Imagini greoaie de încărcare folosind observatorul de intersecție de Dean Hume
  • IntersecțieObserver Exemplu
  • Intersection Observer API pe mozilla.org
  • Lazy Loading imagini cu intersecție Observer de Cory Dowdy
  • Folosind API-ul Intersection Observer pentru a declanșa animații și tranziții pe Alligator.io
  • IntersecțiaObserver vine în vedere de către Surma