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

仿Uber Eats的Angular网页端联动滚动横向分类菜单实现

Angular实现滚动联动分类菜单(替代Bootstrap ScrollSpy)

核心思路

放弃Bootstrap ScrollSpy,直接通过监听窗口滚动事件,计算各分类内容区块的位置,对比当前滚动高度来自动切换菜单的激活状态,逻辑更可控,适配Angular环境。

具体实现步骤

1. 定义分类数据

在组件类里先声明分类列表和当前激活的分类ID:

categories = [
  { id: 'electronics', name: '电子产品' },
  { id: 'clothing', name: '服饰' },
  { id: 'home', name: '家居' }
];
activeCategoryId = 'electronics';

2. 编写页面模板

横向滚动菜单用flex+overflow-x:auto实现,内容区每个分类对应带唯一ID的区块:

<!-- 横向滚动分类菜单 -->
<div class="category-scroll">
  <div 
    *ngFor="let category of categories"
    class="category-item"
    [class.active]="activeCategoryId === category.id"
    (click)="scrollToCategory(category.id)"
  >
    {{ category.name }}
  </div>
</div>

<!-- 分类内容区 -->
<div class="content-container">
  <div id="electronics" class="category-section">
    <!-- 电子产品分类内容 -->
  </div>
  <div id="clothing" class="category-section">
    <!-- 服饰分类内容 -->
  </div>
  <div id="home" class="category-section">
    <!-- 家居分类内容 -->
  </div>
</div>

3. 设置基础样式

给菜单和内容区块添加样式,确保横向滚动和视觉区分:

.category-scroll {
  display: flex;
  overflow-x: auto;
  padding: 1rem 0;
  border-bottom: 1px solid #eee;
  /* 隐藏滚动条(可选) */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.category-scroll::-webkit-scrollbar { display: none; }

.category-item {
  padding: 0.5rem 1rem;
  margin-right: 1rem;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.2s;
}

.category-item.active {
  color: #007bff;
  border-bottom: 2px solid #007bff;
}

.content-container {
  padding: 1rem 0;
}

.category-section {
  min-height: 600px; /* 给每个区块设置最小高度,方便测试滚动 */
  margin-bottom: 2rem;
}

4. 实现滚动联动逻辑

在组件里监听滚动事件,计算区块位置并更新激活状态,同时添加点击菜单滚动到对应区块的功能:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Component({
  selector: 'app-category-scroll',
  templateUrl: './category-scroll.component.html',
  styleUrls: ['./category-scroll.component.css']
})
export class CategoryScrollComponent implements OnInit, OnDestroy {
  categories = [
    { id: 'electronics', name: '电子产品' },
    { id: 'clothing', name: '服饰' },
    { id: 'home', name: '家居' }
  ];
  activeCategoryId = 'electronics';
  scrollSubscription!: Subscription;

  ngOnInit(): void {
    // 监听滚动事件,加防抖避免频繁触发
    this.scrollSubscription = fromEvent(window, 'scroll')
      .pipe(debounceTime(100))
      .subscribe(() => this.updateActiveCategory());
  }

  ngOnDestroy(): void {
    // 销毁订阅,防止内存泄漏
    this.scrollSubscription.unsubscribe();
  }

  updateActiveCategory(): void {
    // 加100px偏移量,让菜单切换时机更贴合视觉感受
    const scrollTop = window.scrollY + 100;
    // 从后往前遍历,确保优先匹配当前可见的最上方区块
    for (let i = this.categories.length - 1; i >= 0; i--) {
      const section = document.getElementById(this.categories[i].id);
      if (section) {
        const sectionTop = section.offsetTop;
        if (scrollTop >= sectionTop) {
          this.activeCategoryId = this.categories[i].id;
          break;
        }
      }
    }
  }

  scrollToCategory(categoryId: string): void {
    const section = document.getElementById(categoryId);
    if (section) {
      // 平滑滚动到对应区块顶部
      section.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }
}

关键细节说明

  • 防抖处理:用debounceTime(100)降低滚动事件触发频率,避免性能损耗。
  • 偏移量调整:scrollTop + 100可根据实际布局调整,让菜单切换时机更自然。
  • 内存泄漏预防:组件销毁时必须取消滚动事件订阅。
  • 平滑滚动:点击菜单时用scrollIntoView实现流畅的滚动效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:50:22