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

React分类切换时实现水平滚动条自动滚动的方法

分类切换自动水平滚动实现方案

核心逻辑是通过DOM ref拿到滚动容器和激活分类项的实例,在激活分类变化时调用原生滚动API,自动将激活项移动到可视区域内,全程不需要引入第三方依赖。

实现步骤

  • 引入需要的React hooks
import { useRef, useEffect, forwardRef } from 'react';
  • 声明ref存储DOM实例
    在分类组件内创建两个ref,分别绑定外层滚动容器、所有分类项的DOM节点:
// 绑定水平滚动容器
const categoryScrollRef = useRef(null);
// 按索引存储每个分类项的DOM
const categoryItemRefs = useRef([]);
  • 给MobileCategory组件添加ref转发
    自定义组件默认不能直接接收ref属性,需要用forwardRef做一层透传,把ref绑定到分类项最外层的DOM节点上:
const MobileCategory = forwardRef(({ categoryName, active, setActiveCategory, id }, ref) => {
  return (
    <div
      ref={ref}
      onClick={() => setActiveCategory(id)}
      className={`px-3 py-1 whitespace-nowrap ${active ? 'text-red-500 font-bold border-b-2 border-red-500' : 'text-gray-600'}`}
    >
      {categoryName}
    </div>
  )
})
  • 给滚动容器和分类项绑定ref
    修改原有渲染代码,把ref绑定到对应节点上:
<div 
  ref={categoryScrollRef}
  className="bg-white p-2 sticky top-0 flex space-x-4 overflow-x-auto overflow-y-hidden border-b border-gray-300 z-10"
>
  {categories?.map((item, index) => {
    const isActive = item.Id.toString() === activeCategory;
    return (
      <MobileCategory
        key={item.Id}
        ref={(el) => (categoryItemRefs.current[index] = el)}
        categoryName={item.Title}
        active={isActive}
        setActiveCategory={setActiveCategory}
        id={item.Id.toString()}
      />
    );
  })}
</div>

提示:把原有overflow-scroll改成overflow-x-auto overflow-y-hidden可以避免垂直方向出现不必要的滚动条。

  • 监听激活分类变化触发滚动
    用useEffect监听activeCategory变化,激活项更新时调用scrollIntoView实现平滑滚动:
useEffect(() => {
  if (!categories || !categoryScrollRef.current) return;
  // 找到当前激活分类的索引
  const activeIndex = categories.findIndex(item => item.Id.toString() === activeCategory);
  const activeItem = categoryItemRefs.current[activeIndex];
  if (activeIndex < 0 || !activeItem) return;

  // 触发滚动
  activeItem.scrollIntoView({
    behavior: 'smooth', // 平滑滚动,改成auto就是瞬间跳转
    block: 'nearest',
    inline: 'center' // 对齐方式:start=靠左、center=居中、end=靠右、nearest=最小滚动距离
  });
}, [activeCategory, categories]);

可选自定义调整

  • 如果需要自定义滚动偏移量(比如让激活项离容器左侧留16px间距),可以不用scrollIntoView,手动计算偏移量调用容器的滚动方法:
// 替换上面useEffect里的scrollIntoView逻辑
const container = categoryScrollRef.current;
const targetLeft = activeItem.offsetLeft - container.offsetLeft - 16;
container.scrollTo({
  left: targetLeft,
  behavior: 'smooth'
});
  • 如果需要隐藏滚动条但保留滚动能力,可以在全局CSS中添加以下样式,再给滚动容器加上scrollbar-hide类名:
.scrollbar-hide::-webkit-scrollbar {
  display: none;
}
.scrollbar-hide {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:51:23