如何在用户点击/触摸/滚动时停止JS滚动到顶部动画?
解决平滑滚动到顶部动画的中途终止问题
要实现用户中途操作时终止滚动动画,核心是利用cancelAnimationFrame取消未执行的动画帧,同时监听用户的交互事件触发终止逻辑。具体实现步骤如下:
- 保存
requestAnimationFrame返回的动画ID,用于后续取消动画 - 监听用户的点击、触摸、鼠标滚动事件,触发时终止动画并清理事件监听
- 优化原滚动函数,确保动画完成后自动清理监听
完整代码示例:
let scrollAnimationId = null; // 保存动画请求ID function scrollToTop() { const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; if (scrollTop > 0) { scrollAnimationId = window.requestAnimationFrame(scrollToTop); window.scrollTo(0, scrollTop - scrollTop / 8); } else { // 动画完成后移除事件监听 removeUserInteractionListeners(); } } function stopScrollAnimation() { if (scrollAnimationId) { window.cancelAnimationFrame(scrollAnimationId); scrollAnimationId = null; removeUserInteractionListeners(); } } function addUserInteractionListeners() { // 监听用户可能中断动画的操作 document.addEventListener('click', stopScrollAnimation); document.addEventListener('touchstart', stopScrollAnimation); document.addEventListener('wheel', stopScrollAnimation); } function removeUserInteractionListeners() { // 移除监听避免内存泄漏 document.removeEventListener('click', stopScrollAnimation); document.removeEventListener('touchstart', stopScrollAnimation); document.removeEventListener('wheel', stopScrollAnimation); } // 调用滚动到顶部前先添加监听 function startScrollToTop() { addUserInteractionListeners(); scrollToTop(); }
关键说明
scrollAnimationId:存储每次requestAnimationFrame的返回值,通过cancelAnimationFrame可以直接终止后续动画帧的执行stopScrollAnimation:统一的终止函数,负责取消动画并清理事件监听,防止重复触发addUserInteractionListeners/removeUserInteractionListeners:集中管理事件监听,动画结束或终止后及时移除,避免不必要的事件绑定
使用时,调用startScrollToTop()即可启动平滑滚动,用户点击页面、触摸屏幕或滚动鼠标时,动画会立即终止,不会出现卡顿问题。
内容的提问来源于stack exchange,提问作者Roger Castillo
相关产品推荐
相关产品推荐

