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

React横向滚动站点实现垂直滚动转横向并兼容scroll-behavior:smooth咨询

问题根源

你原始代码的异常表现来自三个核心问题:

  1. 未阻止滚轮默认行为:浏览器默认的纵向滚动逻辑和你手动修改scrollLeft的逻辑冲突,导致滚动距离被抵消,速度异常变慢
  2. 未区分滚动方向:当用户触发横向滚动(触控板横向滑动、带横向滚轮的鼠标)时,你额外叠加的scrollLeft修改会和原生横向滚动逻辑冲突,造成卡顿
  3. 和scroll-behavior: smooth的冲突:全局CSS设置该属性后,每一次scrollLeft赋值都会触发平滑过渡动画,多次连续赋值会出现动画队列挤压,导致滚动滞后、速度异常、卡顿
完整实现方案

基础滚动转换逻辑(React适配版)

直接在React组件内实现,避免原生全局监听的内存泄漏问题,核心逻辑自动区分横竖滚动,适配不同设备的滚轮参数:

import { useRef, useEffect } from 'react';

const PortfolioGallery = () => {
  const scrollerRef = useRef(null);

  useEffect(() => {
    const scroller = scrollerRef.current;
    if (!scroller) return;

    const handleWheel = (e) => {
      // 原生横向滚动直接交给系统处理,不做额外逻辑
      if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) return;
      
      // 阻止默认纵向滚动行为,避免冲突
      e.preventDefault();
      
      // 自定义滚动速度系数,可根据实际体验调整
      const speedCoefficient = 1.5;
      const scrollIncrement = e.deltaY * speedCoefficient;

      // 用scrollTo方法控制滚动,不直接修改scrollLeft
      scroller.scrollTo({
        left: scroller.scrollLeft + scrollIncrement,
        // 滚轮滚动时关闭平滑动画,避免卡顿
        behavior: 'auto'
      });
    };

    scroller.addEventListener('wheel', handleWheel, { passive: false });
    return () => scroller.removeEventListener('wheel', handleWheel);
  }, []);

  // 按钮平滑跳转的示例方法
  const scrollToSection = (position) => {
    scrollerRef.current?.scrollTo({
      left: position,
      // 主动触发跳转时开启平滑动画
      behavior: 'smooth'
    });
  };

  return (
    <div 
      ref={scrollerRef}
      style={{
        overflowX: 'scroll',
        overflowY: 'hidden',
        msOverflowStyle: 'none',
        scrollbarWidth: 'none',
        // 不要全局设置scroll-behavior: smooth,改为JS按需控制
      }}
    >
      {/* 画廊内容 */}
      <button onClick={() => scrollToSection(1000)}>跳转到指定位置</button>
    </div>
  );
};

圆形滚动适配

要实现圆形滚动的正弦曲线效果,直接取用滚轮事件的deltaX和deltaY做组合计算即可,修改handleWheel里的滚动增量计算逻辑:

const handleWheel = (e) => {
  e.preventDefault();
  const speedCoefficient = 1.5;
  // 组合横竖方向的滚动值,按你需要的正弦规则调整计算逻辑即可
  const scrollIncrement = (e.deltaY + Math.sin(e.deltaX / 100) * 100) * speedCoefficient;
  scroller.scrollTo({
    left: scroller.scrollLeft + scrollIncrement,
    behavior: 'auto'
  });
};

平滑滚动共存说明

不需要全局设置CSS的scroll-behavior: smooth,改为在JS触发滚动时按需指定behavior参数即可:

  • 滚轮触发的滚动转换:指定behavior: 'auto',避免动画冲突导致的卡顿
  • 按钮点击、锚点跳转等主动触发的滚动:指定behavior: 'smooth',保留平滑过渡效果
    两种场景互不影响,完全覆盖你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:48:05