Visualizzazione di IntersectionExampler'

L'osservatorio di osservazione permette di sapere quando un elemento osservato entra o esce dall'area visibile del browser.

Supporto dei browser

  • 51
  • 15
  • 55
  • 12.1

Fonte

Supponiamo che tu voglia monitorare quando un elemento del DOM entra nell'area visibile. In questo modo, puoi eseguire il caricamento lento delle immagini in tempo o perché hai bisogno di sapere se l'utente sta effettivamente guardando un determinato banner dell'annuncio. Puoi farlo collegando l'evento di scorrimento o utilizzando un timer periodico e chiamando getBoundingClientRect() su quell'elemento.

Questo approccio, tuttavia, è molto lento, poiché ogni chiamata a getBoundingClientRect() obbliga il browser a riconfigurare l'intera pagina e introdurrà un considerevole jank sul tuo sito web. Le pratiche diventano quasi impossibili quando sai che il tuo sito viene caricato all'interno di un iframe e vuoi sapere quando l'utente può vedere un elemento. Il modello a origine singola e il browser non consentono di accedere ai dati della pagina web contenente l'iframe. Questo è un problema comune per gli annunci, ad esempio, che vengono caricati di frequente utilizzando iframe.

Rendere più efficiente questo test di visibilità è lo scopo per cui IntersectionObserver è stato progettato ed è disponibile in tutti i browser moderni. IntersectionObserver ti consente di sapere quando un elemento osservato entra o esce nell'area visibile del browser.

Visibilità iframe

Come creare un IntersectionObserver

L'API è piuttosto piccola e la migliore è la descrizione con un esempio:

const io = new IntersectionObserver(entries => {
  console.log(entries);
}, {
  /* Using default options. Details below */
});

// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();

Se utilizzi le opzioni predefinite per IntersectionObserver, il callback viene chiamato sia quando l'elemento diventa parzialmente visibile e quando esce completamente dall'area visibile.

Se hai bisogno di osservare più elementi, è possibile e consigliato di osservare più elementi utilizzando la stessa istanza di IntersectionObserver chiamando observe() più volte.

Un parametro entries viene trasmesso al callback, ovvero un array di oggetti IntersectionObserverEntry. Ciascun oggetto di questo tipo contiene dati di intersezione aggiornati per uno degli elementi osservati.

🔽[IntersectionObserverEntry]
    time: 3893.92
    🔽rootBounds: ClientRect
        bottom: 920
        height: 1024
        left: 0
        right: 1024
        top: 0
        width: 920
    🔽boundingClientRect: ClientRect
    // ...
    🔽intersectionRect: ClientRect
    // ...
    intersectionRatio: 0.54
    🔽target: div#observee
    // ...

rootBounds è il risultato della chiamata di getBoundingClientRect() sull'elemento principale, che è l'area visibile per impostazione predefinita. boundingClientRect è il risultato della chiamata di getBoundingClientRect() sull'elemento osservato. intersectionRect è l'intersezione di questi due rettangoli e indica in modo efficace quale parte dell'elemento osservato è visibile. intersectionRatio è strettamente correlato e indica in che misura l'elemento è visibile. Con queste informazioni a tua disposizione, ora puoi implementare funzionalità come il caricamento just-in-time degli asset prima che diventino visibili sullo schermo. in modo efficiente.

Rapporto di intersezione.

Gli IntersectionObserver pubblicano i propri dati in modo asincrono e il tuo codice di callback verrà eseguito nel thread principale. Inoltre, le specifiche indicano che le implementazioni IntersectionObserver devono utilizzare requestIdleCallback(). Ciò significa che la chiamata al callback fornita ha una priorità bassa e verrà effettuata dal browser durante il tempo di inattività. Si tratta di una decisione di progettazione consapevole.

div a scorrimento

Non sono un grande fan dello scorrimento all'interno di un elemento, ma non sono qui per giudicare e nemmeno IntersectionObserver. L'oggetto options utilizza un'opzione root che consente di definire un'alternativa all'area visibile come principale. È importante tenere presente che root deve essere un predecessore di tutti gli elementi osservati.

Incrocia tutte le cose.

No! Cattivo sviluppatore! Non si tratta di un utilizzo consapevole dei cicli della CPU dell'utente. Prendiamo come esempio uno scorrimento continuo: in questo caso, è sicuramente consigliabile aggiungere sentinel al DOM e osservarli (e riciclarli). Devi aggiungere una sentinella vicino all'ultimo elemento nello scorrimento continuo. Quando quella sentinel viene visualizzata, puoi utilizzare il callback per caricare i dati, creare gli elementi successivi, collegarli al DOM e riposizionare la sentinella di conseguenza. Se ricicli correttamente la sentinella, non è necessaria alcuna chiamata aggiuntiva a observe(). IntersectionObserver continua a funzionare.

Scorrimento infinito

Altri aggiornamenti

Come accennato in precedenza, il callback viene attivato una sola volta quando l'elemento osservato diventa parzialmente visibile e un'altra volta quando lascia l'area visibile. In questo modo IntersectionObserver risponde alla domanda "L'elemento X è visibile?". In alcuni casi d'uso, tuttavia, potrebbe non essere sufficiente.

È qui che entra in gioco l'opzione threshold. Consente di definire un array di soglie di intersectionRatio. Il callback verrà chiamato ogni volta che intersectionRatio incrocia uno di questi valori. Il valore predefinito di threshold è [0] e questo spiega il comportamento predefinito. Se modifichiamo threshold in [0, 0.25, 0.5, 0.75, 1], riceveremo una notifica ogni volta che un ulteriore quarto dell'elemento diventa visibile:

Animazione della soglia.

Altre opzioni?

Al momento, c'è solo un'opzione aggiuntiva rispetto a quelle elencate sopra. rootMargin ti consente di specificare i margini della radice, in modo da aumentare o ridurre l'area utilizzata per gli incroci. Questi margini vengono specificati utilizzando una stringa in stile CSS, ad esempio "10px 20px 30px 40px", che specifica rispettivamente il margine superiore, il margine inferiore e il margine sinistro. Per riepilogare, la struttura delle opzioni IntersectionObserver offre le seguenti opzioni:

new IntersectionObserver(entries => {/* … */}, {
  // The root to use for intersection.
  // If not provided, use the top-level document's viewport.
  root: null,
  // Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
  // If an explicit root element is specified, components may be percentages of the
  // root element size.  If no explicit root element is specified, using a
  // percentage is an error.
  rootMargin: "0px",
  // Threshold(s) at which to trigger callback, specified as a ratio, or list of
  // ratios, of (visible area / total area) of the observed element (hence all
  // entries must be in the range [0, 1]).  Callback will be invoked when the
  // visible ratio of the observed element crosses a threshold in the list.
  threshold: [0],
});

<iframe> magia

Gli IntersectionObserver sono stati progettati specificamente pensando a servizi pubblicitari e widget di social network, che utilizzano spesso elementi <iframe> e potrebbero trarre vantaggio dal sapere se sono visibili. Se <iframe> osserva uno dei suoi elementi, sia lo scorrimento di <iframe> sia la finestra contenente <iframe> attiveranno il callback nei momenti appropriati. Nel secondo caso, tuttavia, rootBounds verrà impostato su null per evitare fughe di dati tra le origini.

Di cosa non tratta IntersectionObserver?

Una cosa da tenere presente è che IntersectionObserver non è intenzionalmente né perfetto per i pixel né a bassa latenza. Il loro utilizzo per implementare sforzi come le animazioni dipendenti dallo scorrimento è destinato a non riuscire, poiché i dati saranno, strettamente parlando, non aggiornati quando potrai utilizzarli. L'spiegazione contiene ulteriori dettagli sui casi d'uso originali di IntersectionObserver.

Quanto lavoro posso fare con la richiamata?

Breve e semplice: se trascorri troppo tempo nella callback, il ritardo dell 'app sarà prolungato. Si applicano tutte le best practice più comuni.

Vai avanti e incrocia i tuoi elementi

Il supporto del browser per IntersectionObserver è buono, poiché è disponibile in tutti i browser moderni. Se necessario, un polyfill può essere utilizzato nei browser meno recenti ed è disponibile nel repository di WiCG. Ovviamente, con il polyfill non potrai usufruire dei vantaggi in termini di rendimento offerti dall'implementazione nativa.

Puoi iniziare a usare subito IntersectionObserver. Facci sapere che cosa ti è venuto in mente.