You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js如何监听滚动结束事件?

嘿,我来帮你搞定这个滚动结束监听的问题!你现在的代码是在滚动过程中触发状态更新,但要监听“滚动结束”,核心思路是用防抖(debounce)——简单说就是等用户停止滚动一小段时间后,再执行我们的逻辑,而不是滚动时一直触发。

原生JS适配React的最优实现

这是不需要第三方库的轻量化方案,直接改造你现有的代码就行:

首先在组件里先定义一个定时器变量(类组件和函数组件的写法略有不同):

// 类组件写法
constructor(props) {
  super(props);
  this.state = { showScrollWidget: false };
  this.scrollTimer = null; // 用来存储定时器引用,方便后续清除
}

// 函数组件写法(用useRef保存定时器)
const scrollTimer = useRef(null);

然后修改你的滚动事件监听逻辑:

window.addEventListener('scroll', () => {
  // 滚动过程中先清除之前的定时器,避免重复触发
  if (this.scrollTimer) clearTimeout(this.scrollTimer);
  
  // 保持你原来的逻辑:滚动时显示组件
  if (!this.state.showScrollWidget) {
    this.setState({ showScrollWidget: true });
  }

  // 设置新的定时器:如果200ms内没有再触发滚动,就判定为滚动结束
  this.scrollTimer = setTimeout(() => {
    // 这里写滚动结束后要执行的逻辑,比如隐藏组件或其他操作
    console.log('滚动结束啦!');
    // 举个例子:如果需要滚动结束后隐藏组件
    // this.setState({ showScrollWidget: false });
  }, 200);
});

关键细节提醒

  • 延迟时间(200ms)可以按需调整:想更灵敏就设150ms,想避免误触发就设300ms。
  • 组件卸载时一定要清理监听和定时器,防止内存泄漏:
// 类组件卸载时
componentWillUnmount() {
  window.removeEventListener('scroll', this.handleScroll);
  if (this.scrollTimer) clearTimeout(this.scrollTimer);
}

// 函数组件卸载时(用useEffect)
useEffect(() => {
  const handleScroll = () => { /* 滚动逻辑 */ };
  window.addEventListener('scroll', handleScroll);
  return () => {
    window.removeEventListener('scroll', handleScroll);
    if (scrollTimer.current) clearTimeout(scrollTimer.current);
  };
}, []);

封装成防抖函数更优雅

如果觉得上面的代码有点零散,可以把滚动结束的逻辑封装成通用防抖函数,复用性更强:

// 通用防抖函数封装
const debounce = (func, delay) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, args), delay);
  };
};

// 组件内的滚动处理函数
handleScroll = () => {
  if (!this.state.showScrollWidget) {
    this.setState({ showScrollWidget: true });
  }
};

// 滚动结束的回调逻辑
handleScrollEnd = () => {
  console.log('滚动结束!');
  // 你的自定义逻辑...
};

// 绑定滚动监听
window.addEventListener('scroll', () => {
  this.handleScroll();
  debounce(this.handleScrollEnd, 200)();
});

第三方工具推荐(适合复杂场景)

如果你的项目需要更多滚动相关功能(比如滚动到指定位置、元素视口检测、滚动方向判断等),可以考虑用专门的React滚动库,比如react-scroll-trigger或者react-infinite-scroll-component——这些库已经封装好了滚动结束、视口进入等常用逻辑,不用自己写原生代码。但如果只是单纯监听滚动结束,原生防抖方案足够轻量,没必要引入额外依赖。

内容的提问来源于stack exchange,提问作者BenFarhat Souhaib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:18:34