Exclua as funções de tempo limite e elimine os bugs delas. Este é 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 disparados tarde ou enquanto o dedo do usuário ainda estivesse na tela. Essa falta de confiabilidade em saber quando a rolagem
realmente terminou levou a bugs e uma experiência ruim para o usuário.
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 seja mais parecido com um evento de rolagem que tenha sido pausado, não como um evento de rolagem
finalizado.
Depois do evento
scrollend
, o navegador faz toda essa avaliação difícil para você.
document.onscrollend = event => {…}
Isso é bom. Temporizado perfeitamente e cheio de condições significativas antes da emissão.
Faça um teste
Detalhes do evento
O evento scrollend
é acionado quando:
- O navegador não está mais animando ou transladando a rolagem.
- O toque do usuário foi liberado.
- O ponteiro do usuário liberou o botão de rolagem.
- O usuário soltou o botão.
- 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 resulta em nenhuma mudança de posição de rolagem (nenhuma tradução ocorreu).
- scrollTo()
não resultou em nenhuma tradução.
Uma das razões para esse evento demorar tanto para chegar à plataforma da Web foi devido aos muitos
pequenos detalhes que precisavam de especificações. Uma das áreas mais complexas
era articular os detalhes do scrollend
para a janela de visualização visual
em relação ao documento. Considere uma página da Web em que você aplica zoom. Você pode rolar
quando estiver nesse estado com zoom, não necessariamente rolando o
documento. Tenha certeza de que mesmo essa interação de rolagem gerada pelo usuário da viewport 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 do evento:
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
Polipreenchimentos e aprimoramento progressivo
Se você quiser usar esse novo evento agora, confira nosso conselho. 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 se o navegador oferece 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
está disponível. Você também pode testar um polyfill (NPM) que eu fiz que faz o melhor que o navegador pode:
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 do navegador, se disponível. Se ele não estiver disponível, o script vai monitorar os eventos do ponteiro e
rolar para fazer a melhor estimativa do término do evento possível.
Casos de uso
É uma boa prática evitar trabalhos computacionalmente pesados enquanto a rolagem está
acontecendo. Essa prática garante que a rolagem seja livre para usar o máximo possível de memória e
processamento, para que a experiência seja tranquila. O uso de um evento scrollend
é o momento perfeito para chamar a atenção e fazer o trabalho árduo, já que 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
interrompeu. Por exemplo:
- Sincronizar uma posição de rolagem do carrossel com um indicador de ponto.
- Sincronizar um item da galeria com os metadados dele.
- Busca de 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 a direita. Depois que o usuário terminar de deslizar, você poderá realizar a ação com base no local para onde ele rolou.
Também é possível usar esse evento para sincronização após a rolagem programática ou do usuário, ou para ações como análise de registros.
Este é um bom exemplo em que vários elementos, como setas, pontos e foco, precisam ser atualizados com base na posição de rolagem. Confira como criei este carrossel no YouTube. Além disso, 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.