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

Next.js集成Lenis React后overflow元素无法滚动的问题求助

Lenis React集成Next.js后内部滚动元素异常的排查与解决思路

我近期将Lenis React组件集成到Next.js应用中,之后页面上带有overflow-scroll类的元素出现滚动异常,集成前该元素滚动功能完全正常。相关CSS样式为:overflow-y-scroll pr-[17px] box-content。

我尝试过以下方案,但均未解决问题:

  • 使用Mantine的ScrollArea组件替代原生滚动容器
  • 设置鼠标悬浮时让滚动容器获取焦点
  • 自定义基于鼠标位置的滚动逻辑(代码如下),但该逻辑是跟随鼠标位置直接跳转滚动,并非我需要的正常滚动效果

自定义滚动逻辑代码:

useEffect(() => {
    const element = carouselContainerRef.current;

    const handleMouseMove = (event) => {
      if (!isScrolling) return;

      // Simplified calculations since we're using the ref directly
      const containerRect = element.getBoundingClientRect();
      const deltaY = event.clientY - containerRect.top;

      const maxScrollTop = element.scrollHeight - element.clientHeight;
      const newScrollTop = Math.min(Math.max(0, deltaY), maxScrollTop);

      element.scrollTop = newScrollTop;
    };

    if (element) {
      element.addEventListener('mousemove', handleMouseMove);
    }
    return () => {
      if (element) {
        // 注:原代码存在错误,此处应为removeEventListener
        element.removeEventListener('mousemove', handleMouseMove);
      }
    };
}, [isScrolling]);

排查方向

  • 检查Lenis的全局滚动拦截:Lenis默认会接管全局滚动事件,可能阻止了内部滚动容器的原生滚动事件冒泡。查看Lenis初始化配置,重点关注touch、wheel等选项是否影响了内部元素。
  • 滚动事件冲突排查:打开浏览器开发者工具的Event Listeners面板,查看滚动容器上的事件监听,确认Lenis是否给它绑定了额外事件或阻止了默认行为。
  • CSS样式冲突检查:Lenis可能会给全局或容器添加pointer-events、touch-action等样式,导致滚动容器无法接收输入事件。检查滚动元素的computed样式,重点看touch-action、pointer-events、overflow相关属性是否被篡改。
  • Next.js渲染机制影响:如果滚动容器是服务端渲染的,Lenis在客户端初始化时可能和DOM元素交互存在延迟,导致滚动事件绑定异常。尝试在useEffect中延迟初始化Lenis,或确保滚动容器在客户端挂载完成后再启用Lenis。

解决思路

  • 给内部滚动容器添加Lenis排除规则:Lenis支持通过配置指定不需要接管的元素,两种方式:
    1. 初始化时配置exclude选项:
      const lenis = new Lenis({
        exclude: '.overflow-scroll'
      })
      
    2. 给滚动容器添加data-lenis-prevent属性:<div className="overflow-scroll" data-lenis-prevent>
  • 手动阻止事件冒泡到Lenis:在滚动容器上添加事件监听,阻止滚动事件冒泡到Lenis的全局监听:
    useEffect(() => {
      const container = carouselContainerRef.current
      if (!container) return
    
      const handleWheel = (e) => e.stopPropagation()
      const handleTouchMove = (e) => e.stopPropagation()
    
      container.addEventListener('wheel', handleWheel)
      container.addEventListener('touchmove', handleTouchMove)
    
      return () => {
        container.removeEventListener('wheel', handleWheel)
        container.removeEventListener('touchmove', handleTouchMove)
      }
    }, [])
    
  • 调整Lenis配置降低影响:修改Lenis的smoothWheel、autoResize等配置,比如关闭平滑滚动对wheel事件的处理:
    const lenis = new Lenis({
      smoothWheel: false
    })
    
  • 修复自定义滚动逻辑:如果要保留自定义逻辑,改成基于滚动增量的正常滚动方式:
    useEffect(() => {
      const element = carouselContainerRef.current
      if (!element) return
    
      const handleWheel = (e) => {
        e.preventDefault()
        element.scrollTop += e.deltaY
      }
    
      element.addEventListener('wheel', handleWheel)
      return () => element.removeEventListener('wheel', handleWheel)
    }, [])
    

内容的提问来源于stack exchange,提问作者Alister Sequeira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:18:32