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

React/Typescript+Emotion实现水平菜单激活按钮自动滚动到视口方案咨询

实现方案

核心思路

利用浏览器原生Element.scrollIntoView()API,在按钮激活时自动滚动到可视区域,无需额外引入第三方库。

具体修改步骤

1. 先修正容器样式笔误

你提供的StyledDiv样式中overflow: auto后缺少分号,会导致后续样式失效,先补上:

const StyledDiv = withTheme(
  styled.div<StyledProps>`
    display: flex;
    flex-wrap: nowrap;
    overflow: auto;
    width: 100%;
    overflow-x: scroll;
    overflow-y: hidden;
    column-gap: 8px;
    -webkit-overflow-scrolling: touch;
    &::-webkit-scrollbar {
      display: none;
   }
  `
)

2. 修改按钮组件,添加滚动逻辑

在按钮组件内引入useRef和useEffect,监听isActive状态,激活时触发滚动:

import { useRef, useEffect } from 'react';

// 组件内部逻辑
const buttonRef = useRef<HTMLButtonElement>(null);

// 监听激活状态,触发滚动
useEffect(() => {
  if (isActive && buttonRef.current) {
    buttonRef.current.scrollIntoView({
      behavior: 'smooth', // 平滑滚动,不需要动画可以设为'auto'
      block: 'nearest', // 垂直方向不滚动
      inline: 'nearest' // 水平方向滚动到刚好完全可见的位置,如果要滚动到视口中间可以改成'center'
    });
  }
}, [isActive]);

return (
  <Button 
    ref={buttonRef}
    data-label={label} 
    isActive={isActive} 
    onClick={() => setActiveCategory(cat)}
  >
    { renderIcon(icon) }
    <Wrapper>
      {label}
      <StyledSpan isActive={isActive}>{label}</StyledSpan>
    </Wrapper>
  </Button>
)

注意事项

  • Emotion的styled生成的原生元素组件默认支持ref透传,无需额外做forwardRef处理
  • 如果需要兼容非常旧的移动端浏览器,可以把scrollIntoView替换为scrollIntoViewIfNeeded,两者效果基本一致
  • 若你的按钮是封装在其他自定义函数组件内,需要手动通过forwardRef转发ref到实际的button DOM元素上

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:45:07