Scrollend, um novo evento JavaScript

Exclua as funções de tempo limite e livre-se dos bugs. O evento que você realmente precisa é "scrollend".

Antes do evento scrollend, não havia uma maneira confiável de detectar se uma rolagem foi concluída. Isso significava que os eventos eram acionados tarde ou enquanto o dedo do usuário ainda estava pressionado na tela. Essa falta de confiabilidade em saber quando a rolagem realmente terminou gerou bugs e uma experiência ruim para o usuário.

Antes
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

O melhor que essa estratégia setTimeout() pode fazer é saber se a rolagem parou para 100ms. Isso faz com que ele se pareça mais com um evento de pausa de rolagem, não um evento de término de rolagem.

Depois do evento scrollend, o navegador faz toda essa avaliação difícil para você.

Depois
document.onscrollend = event => {}

Isso é o que importa. Perfeitamente cronometrado e cheio de condições significativas antes da emissão.

Browser Support

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 109.
  • Safari Technology Preview: supported.

Source

Faça um teste

Detalhes do evento

O evento scrollend é disparado quando: - O navegador não está mais animando ou traduzindo a rolagem. - O toque do usuário foi liberado. - O ponteiro do usuário liberou o controle deslizante da barra de rolagem. - A tecla pressionada pelo usuário foi solta. - A rolagem até o fragmento foi concluída. - O ajuste de rolagem foi concluído. - scrollTo() foi concluído. - O usuário rolou a janela de visualização visual.

O evento scrollend não é acionado quando: - O gesto de um usuário não resultou em mudanças na posição de rolagem (nenhuma tradução ocorreu). - scrollTo() não resultou em nenhuma tradução.

Um dos motivos para esse evento ter demorado tanto para chegar à plataforma da Web foi a quantidade de pequenos detalhes que precisavam de especificações. Uma das áreas mais complexas foi articular os detalhes de scrollend para a janela de visualização visual em comparação com o documento. Considere uma página da Web em que você aumenta o zoom. Você pode rolar a tela quando estiver nesse estado de zoom, e isso não significa necessariamente rolar o documento. Fique tranquilo, mesmo essa interação de rolagem controlada pelo usuário da janela de visualização visual vai emitir o evento scrollend quando for concluída.

Como usar o evento

Assim como outros eventos de rolagem, é possível registrar listeners de algumas maneiras.

addEventListener("scrollend", (event) => {
  // scroll ended
});

aScrollingElement.addEventListener("scrollend", (event) => {
  // scroll ended
});

ou use a propriedade de evento:

document.onscrollend = (event) => {
  // scroll ended
};

aScrollingElement.onscrollend = (event) => {
  // scroll ended
};

Polyfills e aprimoramento progressivo

Se você quiser usar esse novo evento agora, confira nossas melhores dicas. Você pode continuar usando sua estratégia atual de fim de rolagem (se tiver uma) e, no início dela, verificar o suporte com:

'onscrollend' in window
// true, if available

Isso vai informar verdadeiro ou falso, dependendo de o navegador oferecer o evento. Com essa verificação, você pode ramificar o código:

if ('onscrollend' in window) {
  document.onscrollend = callback
}
else {
  document.onscroll = event => {
    clearTimeout(window.scrollEndTimer)
    window.scrollEndTimer = setTimeout(callback, 100)
  }
}

Esse é um bom começo para melhorar progressivamente seu evento scrollend quando ele estiver disponível. Você também pode tentar um polyfill (NPM) que eu criei e que faz o melhor que o navegador pode fazer:

import {scrollend} from "scrollyfills"

// then use scrollend as if it's existed this whole time
document.onscrollend = callback

O polyfill vai melhorar progressivamente para usar o evento scrollend integrado ao navegador, se disponível. Se não estiver disponível, o script vai observar eventos de ponteiro e rolar para fazer a melhor estimativa possível do fim do evento.

Casos de uso

É uma boa prática evitar trabalhos computacionalmente pesados enquanto a rolagem está acontecendo. Essa prática garante que a rolagem possa usar o máximo de memória e processamento possível para manter a experiência fluida. Usar um evento scrollend é o momento perfeito para chamar a atenção e fazer o trabalho pesado, porque a rolagem não está mais acontecendo.

O evento scrollend pode ser usado para acionar várias ações. Um caso de uso comum é sincronizar elementos de interface associados com a posição em que a rolagem parou. Por exemplo: - Sincronizar a posição de rolagem de um carrossel com um indicador de ponto. - Sincronizar um item da galeria com os metadados dele. - Buscar dados depois que um usuário rola para uma nova guia.

Imagine um cenário em que um usuário desliza um e-mail para fora da tela. Depois que eles terminarem de deslizar, você poderá realizar a ação com base em onde eles rolaram.

Você também pode usar esse evento para sincronizar após rolagem programática ou do usuário, ou ações como registro de análises.

Confira um bom exemplo em que vários elementos, como setas, pontos e foco, precisam ser atualizados com base na posição de rolagem. Assista no YouTube como eu criei este carrossel. Teste a demonstração ao vivo.

Agradecemos a Mehdi Kazemi pelo trabalho de engenharia e a Robert Flack pelas orientações sobre API e implementação.