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

React项目中如何获取Smooth-Scrollbar的滚动偏移值?

解决smooth-scrollbar替换原生滚动后的滚动状态获取与事件监听问题

我明白你遇到的困扰——smooth-scrollbar带来流畅体验的同时,接管了原生滚动逻辑,导致window.scrollY和原生onScroll事件全部失效,核心原因就是它生成的.scroll-content容器成为了实际滚动的主体,而window本身的尺寸固定不再滚动。不过不用手动去解析transform属性,smooth-scrollbar本身提供了更可靠的官方API来处理滚动状态和事件,当然如果确实需要读取transform我也会告诉你方法。

方法一:使用smooth-scrollbar官方API(推荐)

首先,你需要保存scrollbar的实例引用,这样才能调用它的方法和监听事件。修改你的SmoothScrollbar.js:

import { useEffect, useRef } from 'react';
import Scrollbar from 'smooth-scrollbar';
import OverscrollPlugin from 'smooth-scrollbar/plugins/overscroll'

// 先定义overscroll配置,避免变量提升问题
const overscrolloptions = {
  enable: true,
  damping: 0.1,
  effect: "bounce",
  maxOverscroll: 150
}

const options = {
  damping: 0.05,
  plugins: {
    overscroll: overscrolloptions
  }
}

const Scroll = () => {
  // 用useRef保存scrollbar实例,方便后续调用
  const scrollbarRef = useRef(null);

  useEffect(() => {
    Scrollbar.use(OverscrollPlugin);
    // 初始化并保存实例
    scrollbarRef.current = Scrollbar.init(document.body, options);

    // 监听滚动事件(替代原生window.onscroll)
    const handleScroll = () => {
      // 通过实例的offset属性获取滚动位置,完全替代window.scrollY
      const scrollY = scrollbarRef.current.offset.y;
      console.log('当前滚动位置Y:', scrollY);
      // 这里可以写入你原来在原生onScroll中的逻辑
    };

    // 添加滚动监听
    scrollbarRef.current.addListener(handleScroll);

    // 组件卸载时清理资源,避免内存泄漏
    return () => {
      scrollbarRef.current.removeListener(handleScroll);
      scrollbarRef.current.destroy();
    };
  }, [])

  return null;
}

export default Scroll;

核心要点:

  • 用useRef持久化保存scrollbar实例,避免组件重新渲染时丢失引用
  • 通过scrollbarRef.current.offset.y获取当前滚动位置,完全替代window.scrollY
  • 用addListener方法注册滚动事件,替代原生的onScroll绑定
  • 组件卸载时必须销毁实例并移除监听,防止内存泄漏

方法二:手动获取.scroll-content的transform属性(不推荐)

如果你确实需要读取那个容器的transform属性,可以这样做:

// 在需要获取的组件或逻辑中执行
const scrollContentEl = document.querySelector('.scroll-content');
if (scrollContentEl) {
  // 获取元素计算后的实际样式
  const computedStyle = window.getComputedStyle(scrollContentEl);
  const transformValue = computedStyle.transform;
  
  // 解析translate3d的Y值:transform值会以matrix3d格式返回,m42对应Y轴偏移
  const matrix = new DOMMatrix(transformValue);
  const translateY = matrix.m42; // 这个值就是translate3d的Y分量(负数表示向下滚动)
  
  console.log('.scroll-content的translateY:', translateY);
}

注意事项:

这种方法完全依赖于smooth-scrollbar的内部实现,一旦插件更新改变了transform的使用逻辑,这段代码就会失效,所以优先推荐使用官方API。

在其他组件中共享scrollbar实例

如果需要在Navbar、Home等组件中访问scrollbar实例,可以通过React Context来传递:

  1. 先创建一个Context文件:
// ScrollbarContext.js
import { createContext, useContext } from 'react';

const ScrollbarContext = createContext(null);

export const ScrollbarProvider = ({ children, scrollbar }) => {
  return (
    <ScrollbarContext.Provider value={scrollbar}>
      {children}
    </ScrollbarContext.Provider>
  );
};

export const useScrollbar = () => useContext(ScrollbarContext);
  1. 修改Scroll组件,用Provider包裹子组件:
// 修改后的Scroll组件
const Scroll = ({ children }) => {
  const scrollbarRef = useRef(null);

  useEffect(() => {
    // 初始化代码保持不变
    Scrollbar.use(OverscrollPlugin);
    scrollbarRef.current = Scrollbar.init(document.body, options);
    
    return () => {
      scrollbarRef.current.destroy();
    };
  }, [])

  return (
    <ScrollbarProvider scrollbar={scrollbarRef.current}>
      {children}
    </ScrollbarProvider>
  );
}
  1. 在App.js中调整组件结构:
// App.js
const App = () => {
  return (
    <Scroll>
      <Navbar/>
      <Switch>
        <Route exact path="/comming-soon" component={CommingSoon}/>
        <Route exact path="/" component={Home}/>
      </Switch>
    </Scroll>
  );
};

之后在Navbar等组件中,就可以用useScrollbar()获取实例,进而监听滚动或获取滚动位置了。


内容的提问来源于stack exchange,提问作者Arbaz Ahmed Khatri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 10:47:30