FNSP Web Page

Saber quando algo entra no ecrã: IntersectionObserver

Carregar imagens só quando são precisas, animar uma secção quando ela aparece, marcar no menu o capítulo que está a ser lido: são três funcionalidades diferentes com o mesmo problema por baixo — saber o que está visível.

A forma antiga era ouvir o evento scroll e medir posições. Corria dezenas de vezes por segundo, na mesma thread que desenha a página, e era a origem clássica do scroll aos solavancos.

O IntersectionObserver faz a mesma pergunta ao browser, que já sabe a resposta — e avisa só quando muda.

1. O básico

const observador = new IntersectionObserver((entradas) => {
  for (const entrada of entradas) {
    if (entrada.isIntersecting) {
      entrada.target.classList.add('visivel');
      observador.unobserve(entrada.target); // uma vez chega
    }
  }
});

document.querySelectorAll('.animar').forEach((elemento) => observador.observe(elemento));

O unobserve depois do primeiro encontro não é detalhe: sem ele, o callback volta a correr a cada entrada e saída do ecrã.

2. As três opções que interessam

new IntersectionObserver(callback, {
  // Começar a tratar 200px antes de entrar no ecrã — é o que dá a sensação
  // de que a imagem "já lá estava".
  rootMargin: '200px',

  // Que fração tem de estar visível para contar. 0 = um pixel basta;
  // 1 = tem de estar inteiro; um array avisa em vários pontos.
  threshold: 0.5,

  // O contentor. Por omissão é a janela; pode ser um div com scroll próprio.
  root: document.querySelector('#lista'),
});

3. Scroll infinito, em oito linhas

const sentinela = document.querySelector('#fim-da-lista');

const observador = new IntersectionObserver(async ([entrada]) => {
  if (!entrada.isIntersecting) return;
  observador.unobserve(sentinela);
  await carregarPaginaSeguinte();
  observador.observe(sentinela);
});

observador.observe(sentinela);

4. E para imagens, se calhar nem é preciso

Antes de escrever qualquer observador para carregar imagens, lembre-se que o browser já faz isso sozinho:

<img src="foto.jpg" loading="lazy" width="800" height="600" alt="" />

O loading="lazy" resolve o caso comum. O observador fica para quando é preciso fazer outra coisa quando algo aparece — e não apenas carregá-lo.

Comentários

Ainda ninguém comentou este artigo.

Voltar ao blog

Gostávamos de saber quantas pessoas visitam o site, com o Google Analytics. Sem a sua autorização não corre nada. Política de Privacidade.