Visualizzazione di IntersectionExampler'

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

Supporto dei browser

  • 51
  • 15
  • 55
  • 12.1

Origine

Supponiamo di voler monitorare quando un elemento del DOM entra nell'area visibile visibile. Ciò può essere utile per eseguire il caricamento lento delle immagini in tempo o per sapere se l'utente sta effettivamente guardando un determinato banner pubblicitario. Puoi farlo collegando l'evento di scorrimento o utilizzando un timer periodico e chiamando getBoundingClientRect(). su quell'elemento.

Tuttavia, questo approccio risulta estremamente lento poiché ogni chiamata a getBoundingClientRect() obbliga il browser a ridefinire il layout dell'intera pagina e introdurrà una notevole capacità di jank per il tuo sito web. Le pratiche diventano impossibili se sai che il tuo sito viene caricato all'interno di un iframe e vuoi sapere quando l'utente può visualizzare 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 per gli annunci, ad esempio, che vengono caricati spesso tramite iframe.

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

Visibilità iframe

Come creare un IntersectionObserver

L'API è piuttosto piccola e viene 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 diventa parzialmente visibile sia quando esce completamente dall'area visibile.

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

Un parametro entries viene passato 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 a 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 ti indica efficacemente quale parte dell'elemento osservato è visibile. intersectionRatio è strettamente correlato e ti indica quanto è visibile l'elemento. Grazie a queste informazioni, 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 pubblicano 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 progettazione consapevole.

div a scorrimento

Lo scorrimento all'interno di un elemento non mi piace molto, 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! Questo non rappresenta l'utilizzo consapevole dei cicli della CPU dell'utente. Prendiamo come esempio uno scorrimento continuo: in questo scenario, è sicuramente consigliabile aggiungere sentinel al DOM e osservarle (e riciclarle). Dovresti aggiungere una sentinella vicino all'ultimo elemento dello scorrimento infinito. Quando la sentinella 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 sono necessarie ulteriori chiamate a observe(). Il IntersectionObserver continua a funzionare.

Scorrimento continuo

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 dà una risposta alla domanda "L'elemento X è visualizzato?". 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 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, esiste una sola 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, lo struct 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 in modo specifico per i servizi pubblicitari e i 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, sia lo scorrimento del <iframe> sia lo scorrimento della finestra contenente il <iframe> attiveranno il callback nei momenti appropriati. In quest'ultimo caso, tuttavia, il criterio rootBounds verrà impostato su null per evitare la fuga di dati tra le origini.

Quali sono gli argomenti non di IntersectionObserver?

Tieni presente che IntersectionObserver non è intenzionalmente né perfetto per pixel né a bassa latenza. Il loro utilizzo per implementare attività come le animazioni dipendenti dallo scorrimento non riuscirà, perché i dati, in definitiva, non saranno aggiornati quando li utilizzerai. L'spiegatore contiene ulteriori dettagli sui casi d'uso originali di IntersectionObserver.

Quanto posso fare durante la richiamata?

Short 'n Sweet: trascorrere troppo tempo nella richiamata comporterà un ritardo nella tua app; si applicano tutte le prassi comuni.

Vai avanti e interseca i tuoi elementi

Il supporto browser per IntersectionObserver è buono, poiché è disponibile in tutti i browser moderni. Se necessario, nei browser meno recenti è possibile utilizzare un polyfill, disponibile nel repository di WiCG. Ovviamente, il polyfill non ti consente di ottenere i vantaggi in termini di prestazioni offerti da un'implementazione nativa.

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