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

React应用中实现隐藏滚动条的div横向滚动并支持拖拽滚动的解决方案

React应用中实现隐藏滚动条的div横向滚动并支持拖拽滚动的解决方案

嘿,我明白你的需求啦——想要横向滚动的按钮容器,隐藏掉丑丑的滚动条,还能让用户按住按钮拖动来滚动,对吧?这里有几个常用的解决办法,你可以试试看:

方法一:自定义鼠标拖拽滚动逻辑

这个方法不需要依赖第三方库,纯JS实现,灵活性拉满。核心思路是监听鼠标的按下、移动、松开事件,计算鼠标位移来调整容器的scrollLeft值。

首先给容器加个ref,然后在组件里处理相关事件:

import { useRef, useEffect } from 'react';
import Tooltip from '@mui/material/Tooltip';
import IconButton from '@mui/material/IconButton';
import ZoomInIcon from '@mui/icons-material/ZoomIn';

const ScrollableButtons = () => {
  const scrollContainerRef = useRef(null);
  let isDragging = false;
  let startX;
  let scrollLeft;

  const handleMouseDown = (e) => {
    isDragging = true;
    startX = e.pageX - scrollContainerRef.current.offsetLeft;
    scrollLeft = scrollContainerRef.current.scrollLeft;
    // 给用户反馈:现在可以拖拽啦
    scrollContainerRef.current.style.cursor = 'grabbing';
  };

  const handleMouseMove = (e) => {
    if (!isDragging) return;
    e.preventDefault();
    const x = e.pageX - scrollContainerRef.current.offsetLeft;
    const walk = (x - startX) * 2; // 调整这个乘数可以改变拖拽灵敏度
    scrollContainerRef.current.scrollLeft = scrollLeft - walk;
  };

  const handleMouseUp = () => {
    isDragging = false;
    scrollContainerRef.current.style.cursor = 'grab';
  };

  const handleMouseLeave = () => {
    isDragging = false;
    scrollContainerRef.current.style.cursor = 'grab';
  };

  useEffect(() => {
    const container = scrollContainerRef.current;
    if (!container) return;
    
    // 绑定事件监听
    container.addEventListener('mousedown', handleMouseDown);
    container.addEventListener('mousemove', handleMouseMove);
    container.addEventListener('mouseup', handleMouseUp);
    container.addEventListener('mouseleave', handleMouseLeave);

    // 组件卸载时清理事件
    return () => {
      container.removeEventListener('mousedown', handleMouseDown);
      container.removeEventListener('mousemove', handleMouseMove);
      container.removeEventListener('mouseup', handleMouseUp);
      container.removeEventListener('mouseleave', handleMouseLeave);
    };
  }, []);

  const doSomething = () => {
    // 你的按钮点击逻辑
    console.log('Button clicked!');
  };

  return (
    <div ref={scrollContainerRef} className="scroll-container">
      <Tooltip title="Button 1">
        <IconButton onClick={doSomething}>
          <ZoomInIcon />
        </IconButton>
      </Tooltip>
      <Tooltip title="Button 2">
        <IconButton onClick={doSomething}>
          <ZoomInIcon />
        </IconButton>
      </Tooltip>
      {/* 更多按钮... */}
    </div>
  );
};

export default ScrollableButtons;

对应的CSS保持你原来的隐藏滚动条样式,再加上拖拽光标提示:

.scroll-container {
  display: flex;
  overflow-x: auto;
  /* 隐藏滚动条 */
  -ms-overflow-style: none; /* IE and Edge */
  scrollbar-width: none; /* Firefox */
  cursor: grab; /* 默认光标状态 */
}

.scroll-container::-webkit-scrollbar {
  display: none; /* Chrome, Safari and Opera */
}

.scroll-container:active {
  cursor: grabbing; /* 拖拽时的光标状态 */
}

这个方法的好处是完全可控,你可以自定义拖拽灵敏度、光标样式等,兼容性也很好。

方法二:使用第三方拖拽滚动库

如果你不想自己写逻辑,可以用现成的库,比如react-dragscroll,它封装好了拖拽滚动的功能,用起来超简单。

首先安装依赖:

npm install react-dragscroll
# 或者用yarn
yarn add react-dragscroll

然后在组件里直接使用:

import DragScroll from 'react-dragscroll';
import Tooltip from '@mui/material/Tooltip';
import IconButton from '@mui/material/IconButton';
import ZoomInIcon from '@mui/icons-material/ZoomIn';

const ScrollableButtons = () => {
  const doSomething = () => {
    console.log('Button clicked!');
  };

  return (
    <DragScroll className="scroll-container">
      <Tooltip title="Button 1">
        <IconButton onClick={doSomething}>
          <ZoomInIcon />
        </IconButton>
      </Tooltip>
      <Tooltip title="Button 2">
        <IconButton onClick={doSomething}>
          <ZoomInIcon />
        </IconButton>
      </Tooltip>
      {/* 更多按钮... */}
    </DragScroll>
  );
};

export default ScrollableButtons;

CSS还是用你原来的隐藏滚动条样式就行:

.scroll-container {
  display: flex;
  overflow-x: auto;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.scroll-container::-webkit-scrollbar {
  display: none;
}

这种方法的优点是代码量极少,能快速实现需求,适合不想折腾自定义逻辑的场景。

方法三:优化移动端触摸体验

如果你的需求重点在移动端,可以加上touch-action: pan-x来确保触摸拖拽正常工作,同时隐藏滚动条:

.scroll-container {
  display: flex;
  overflow-x: auto;
  -ms-overflow-style: none;
  scrollbar-width: none;
  touch-action: pan-x; /* 允许横向触摸滚动 */
}

.scroll-container::-webkit-scrollbar {
  display: none;
}

这个可以配合前面的方法一起用,大幅提升移动端用户体验。


备注:内容来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:43:15