Visualizzazione di IntersectionExampler'

IntersectionObserver ti consente di sapere quando un elemento osservato entra o esce dall'area visibile del browser.

Supporto dei browser

  • Chrome: 51.
  • Edge: 15.
  • Firefox: 55.
  • Safari: 12.1.

Origine

Supponiamo di voler monitorare quando un elemento del DOM entra nell'area visibile visibile. Potresti volerlo fare per caricare le immagini in modo lazy just in time o perché devi 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.

Tuttavia, questo approccio è estremamente lento perché ogni chiamata a getBoundingClientRect() costringe il browser a riorganizzare l'intera pagina e introduce notevoli problemi di aggiornamento nel tuo sito web. Le cose si complicano 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 ti permettono di accedere ai dati della pagina web che contiene l'iframe. Questo è un problema comune, ad esempio, per gli annunci che vengono caricati di frequente utilizzando iframe.

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

Visibilità iframe

Come creare un IntersectionObserver

L'API è piuttosto piccola e può essere descritta meglio utilizzando 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 verrà chiamato sia quando l'elemento viene visualizzato parzialmente sia quando esce completamente dall'area visibile.

Se devi osservare più elementi, è possibile e consigliabile farlo utilizzando la stessa istanza IntersectionObserver chiamando observe() più volte.

Al callback viene passato un parametro entries, che è un array di oggetti IntersectionObserverEntry. Ciascuno di questi oggetti contiene dati aggiornati sull'intersezione 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 getBoundingClientRect() sull'elemento principale, che per impostazione predefinita è l'area visibile. boundingClientRect è il risultato di getBoundingClientRect() chiamato 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 quanto dell'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.

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

Elementi div con scorrimento

Lo scorrimento all'interno di un elemento non mi piace molto, ma non sono qui per giudicare e nemmeno IntersectionObserver. L'oggetto options accetta un'opzione root che ti consente di definire un'alternativa al viewport come elemento principale. È importante tenere presente che root deve essere un antenato di tutti gli elementi osservati.

Intersezione di tutte le cose.

No! Cattivo sviluppatore! Questo non rappresenta l'utilizzo consapevole dei cicli della CPU dell'utente. Prendiamo ad esempio uno scroller infinito: in questo caso, è consigliabile aggiungere sentinelle al DOM e osservarle (e riciclarle!). Devi aggiungere un elemento sentinella vicino all'ultimo elemento nello scorrimento infinito. Quando viene visualizzata la sentinella, puoi utilizzare il callback per caricare i dati, creare gli elementi successivi, collegarli al DOM e riposizionare la sentinella di conseguenza. Se ricicli correttamente il sentinel, non è necessaria un'ulteriore chiamata a observe(). IntersectionObserver continua a funzionare.

Dispositivo di scorrimento infinito

Altri aggiornamenti, per favore

Come accennato in precedenza, il callback verrà attivato una sola volta quando l'elemento osservato diventa parzialmente visibile e un'altra volta quando ha lasciato l'area visibile. In questo modo, IntersectionObserver ti fornisce una risposta alla domanda "L'elemento X è visibile?". Tuttavia, in alcuni casi d'uso, potrebbe non essere sufficiente.

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

Animazione della soglia.

Altre opzioni?

Al momento, esiste un'unica opzione aggiuntiva rispetto a quelle elencate sopra. rootMargin consente di specificare i margini per la radice, in modo da aumentare o ridurre l'area utilizzata per le incroci. Questi margini vengono specificati mediante una stringa in stile CSS, ovvero la "10px 20px 30px 40px", che specifica rispettivamente i margini superiore, destro, inferiore e sinistro. In sintesi, la struttura di 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> magico

I IntersectionObserver sono stati progettati appositamente tenendo conto dei servizi pubblicitari e dei widget dei social network, che utilizzano spesso elementi <iframe> e potrebbero trarre vantaggio dal sapere se sono visibili. Se un <iframe> osserva uno dei suoi elementi, lo scorrimento dell'elemento <iframe> e della finestra che contiene l'elemento <iframe> attiveranno il callback nei momenti opportuni. Tuttavia, in quest'ultimo caso, rootBounds verrà impostato su null per evitare la fuga di dati tra le origini.

Di cosa parla IntersectionObserver Non?

Tieni presente che IntersectionObserver non è intenzionalmente né con una qualità pixel perfetta né a bassa latenza. Se li utilizzi per implementare iniziative come animazioni dipendenti dallo scorrimento, il risultato sarà fallimentare, in quanto i dati saranno, in senso stretto, obsoleti quando li utilizzerai. L'articolo esplicativo contiene ulteriori dettagli sui casi d'uso originali di IntersectionObserver.

Quanto lavoro posso fare nel callout?

Breve e conciso: se il callback richiede troppo tempo, l'app subirà un ritardo. Si applicano tutte le pratiche comuni.

Vai avanti e interseca i tuoi elementi

Il supporto del browser per IntersectionObserver è buono, poiché è disponibile in tutti i browser moderni. Se necessario, è possibile utilizzare un polyfill nei browser meno recenti ed è disponibile nel repository del WICD. Ovviamente, utilizzando il polyfill non otterrai i vantaggi in termini di prestazioni di un'implementazione nativa.

Puoi iniziare a utilizzare IntersectionObserver subito. Dicci cosa hai trovato.