You need to enable JavaScript to run this app. React函数组件实现分类筛选按钮点击后高亮并定位对应区块
优惠活动
大模型
产品
解决方案
定价
更多

React函数组件实现分类筛选按钮点击后高亮并定位对应区块

实现方案

核心交互可拆解为两个独立的逻辑模块:点击分类触发对应区块的平滑滚动、被选中的按钮保持高亮标识当前所处分类。

核心改造步骤

  • 在父组件中新增当前选中分类的状态变量,作为按钮高亮的判断依据
  • 给每个分类对应的内容区块配置唯一、与分类名规则绑定的id属性,作为滚动定位的锚点
  • 点击按钮的回调中,先更新选中状态,再通过原生DOM方法定位目标区块并触发平滑滚动
  • 给处于选中状态的按钮追加自定义样式类,区分普通按钮的视觉效果

代码实现

1. 父组件逻辑(状态管理+滚动触发)

import { useState, useCallback } from 'react'

function MenuContainer() {
  // 默认选中全部分类
  const [activeCategory, setActiveCategory] = useState('全部')
  const categories = ['全部', '早餐', '午餐', '晚餐', '奶昔']

  const handleCategoryClick = useCallback((selectedCategory) => {
    // 更新当前激活分类
    setActiveCategory(selectedCategory)
    // 生成目标区块的匹配id:全部分类对应外层容器,其余分类统一转小写、空格替换为短横线
    const targetId = selectedCategory === '全部' 
      ? 'menu-content-wrapper' 
      : selectedCategory.toLowerCase().replace(/\s+/g, '-')
    const targetElement = document.getElementById(targetId)
    if (targetElement) {
      targetElement.scrollIntoView({
        behavior: 'smooth',
        block: 'start'
      })
    }
  }, [])

  return (
    <div>
      <Categories 
        categories={categories}
        filter={handleCategoryClick}
        activeCategory={activeCategory}
      />
      {/* 分类区块容器 */}
      <div id="menu-content-wrapper" className="menu-list">
        <section id="breakfast" className="category-block">
          <h3>早餐</h3>
          {/* 早餐菜品列表 */}
        </section>
        <section id="lunch" className="category-block">
          <h3>午餐</h3>
          {/* 午餐菜品列表 */}
        </section>
        {/* 晚餐、奶昔区块按相同规则配置id即可 */}
      </div>
    </div>
  )
}

2. 改造后的Categories组件(支持高亮状态)

const Categories = ({ categories, filter, activeCategory }) => {
  return (
    <div className="btn-container">
      {categories.map((category, index) => {
        const isActive = category === activeCategory
        return (
          <button
            type="button"
            className={`filter-btn ${isActive ? 'filter-btn--active' : ''}`}
            key={index}
            onClick={() => filter(category)}
          >
            {category}
          </button>
        );
      })}
    </div>
  );
};

3. 配套样式配置

/* 按钮基础样式 */
.filter-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: #333;
  cursor: pointer;
  transition: all 0.2s ease;
}

/* 选中态按钮自定义样式,可根据设计调整背景、文字色 */
.filter-btn--active {
  background: #ff5722;
  color: #fff;
}

/* 基础平滑滚动配置 */
html {
  scroll-behavior: smooth;
}

/* 适配固定顶部导航的滚动偏移,数值与顶部导航高度保持一致即可 */
.category-block {
  scroll-margin-top: 80px;
  margin-top: 48px;
}

注意事项

  • 区块的id生成规则必须和点击时查找id的规则完全匹配,避免出现元素找不到、滚动失效的问题
  • 当分类名称包含大写、空格时,统一通过规则转成小写短横线格式生成id,保证命名一致性
  • 不需要引入额外的路由、滚动类第三方库,原生scrollIntoView即可覆盖绝大多数平滑滚动场景
  • 用scroll-margin-top配置区块滚动偏移,比手动计算滚动位置稳定性更高,可适配不同高度的顶部固定导航

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 11:36:08