Exclua as funções de tempo limite e elimine os bugs delas. Aqui está o evento de que você realmente precisa: scrollend.
Antes do evento scrollend
, não havia uma maneira confiável de detectar que uma rolagem
foi concluída. Isso significava que os eventos seriam disparados tarde ou enquanto o dedo do usuário
ainda estivesse na tela. Essa falta de confiabilidade em saber quando a rolagem
finalmente terminou, resultando em bugs e em uma experiência ruim para o usuário.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
A melhor estratégia que essa estratégia de setTimeout()
pode fazer é saber se a rolagem parou em
100ms
. Isso faz com que seja mais como um evento de rolagem pausado, não um evento de rolagem
encerrado.
Após o evento
scrollend
, o navegador faz toda essa avaliação difícil para você.
document.onscrollend = event => {…}
Essa é a melhor coisa. No momento certo e cheio de condições significativas antes de emitir.
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 soltou o polegar de rolagem.
- A tecla do usuário foi liberada.
- A rolagem para 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.
O evento scrollend
não é acionado quando:
- Um gesto do usuário não resultou em nenhuma mudança de posição de rolagem (nenhuma translação ocorreu).
- scrollTo()
não resultou em nenhuma tradução.
Um motivo para esse evento demorar tanto para chegar à plataforma da Web se deve aos muitos
pequenos detalhes que precisavam de detalhes de especificação. 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
quando estiver nesse estado com zoom sem precisar rolar o
documento. Mesmo essa interação de rolagem orientada pelo usuário da janela de visualização visual
vai emitir o evento scrollend
quando ele for concluído.
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
};
Polyfills e aprimoramento progressivo
Se você pretende usar esse novo evento agora, aqui está nosso melhor conselho. É possível continuar usando sua estratégia atual de rolagem final, caso tenha uma. No início, verifique o suporte com:
'onscrollend' in window
// true, if available
Verdadeiro ou falso, dependendo se o navegador oferece o evento. Com essa verificação, é possível 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 começo saudável para melhorar progressivamente seu evento scrollend
quando ele
está disponível. Você também pode testar um
polyfill
(NPM) criado por mim 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 será aprimorado progressivamente para usar o evento scrollend
integrado do navegador, se disponível. Se não estiver disponível, o script observa os eventos de ponteiro e
rola a tela para fazer a melhor estimativa do final do evento possível.
Casos de uso
É recomendável evitar trabalho de computação intensa enquanto a rolagem está
acontecendo. Essa prática garante que a rolagem seja livre para usar o máximo de memória e
processamento possível para manter a experiência tranquila. O uso de um evento scrollend
fornece o momento perfeito para chamar e fazer o trabalho duro, 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 da 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 seus metadados.
- Buscar dados depois que o usuário acessar uma nova guia.
Imagine uma situação como um usuário deslizando para fora de um e-mail. Depois que eles terminam de deslizar, é possível realizar a ação com base no local para onde eles rolaram.
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.
Confira um bom exemplo em que vários elementos, como setas, pontos e foco, precisam ser atualizados com base na posição de rolagem. Veja como eu criei esse carrossel no YouTube. Além disso, teste a demonstração ao vivo.
Agradecemos a Mehdi Kazemi pelo trabalho de engenharia e a Robert Flack para orientações sobre API e implementação.