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

如何在Angular中实现类似Uber Eats的滚动分类栏及动态定位

实现Angular滚动分类栏动态高亮当前视图分类

要实现滚动时自动高亮当前视图对应的分类,你需要添加滚动监听逻辑,结合元素位置判断来更新激活状态,以下是具体修改方案:

1. 更新组件TypeScript代码

添加激活分类变量、滚动监听及位置判断逻辑,同时处理跳转时的激活状态同步:

import { Component, ElementRef, ViewChild, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-content',
  templateUrl: './content.component.html',
  styleUrls: ['./content.component.css']
})
export class ContentComponent implements OnInit, OnDestroy {
  @ViewChild('pageContent') pageContent!: ElementRef;
  currentActiveCategory: string = '';
  scrollListener?: () => void;

  scrollToCategory(category: string) {
    const element = document.getElementById(category);
    if (element) {
      element.scrollIntoView({ behavior: 'smooth', block: 'start' });
      this.currentActiveCategory = category; // 跳转时直接同步激活状态
    }
  }

  categories = ['Category 1', 'Category 2', 'Category 3','Category 4', 'Category 5', 'Category 6', 'Category 7','Category 8'];
  items : any = {
    'Category 1': ['Item 1', 'Item 2', 'Item 3'],
    'Category 2': ['Item 4', 'Item 5', 'Item 6'],
    'Category 3': ['Item 7', 'Item 8', 'Item 9'],
    'Category 4': ['Item 7', 'Item 8', 'Item 9'],
    'Category 5': ['Item 1', 'Item 2', 'Item 3'],
    'Category 6': ['Item 4', 'Item 5', 'Item 6'],
    'Category 7': ['Item 7', 'Item 8', 'Item 9'],
    'Category 8': ['Item 7', 'Item 8', 'Item 9'],
    'Category 9': ['Item 1', 'Item 2', 'Item 3'],
    'Category 10': ['Item 4', 'Item 5', 'Item 6'],
    'Category 11': ['Item 7', 'Item 8', 'Item 9'],
    'Category 12': ['Item 7', 'Item 8', 'Item 9'],
    'Category 13': ['Item 1', 'Item 2', 'Item 3'],
    'Category 14': ['Item 4', 'Item 5', 'Item 6'],
    'Category 15': ['Item 7', 'Item 8', 'Item 9'],
    'Category 16': ['Item 7', 'Item 8', 'Item 9'],
    'Category 17': ['Item 1', 'Item 2', 'Item 3'],
    'Category 18': ['Item 4', 'Item 5', 'Item 6'],
    'Category 19': ['Item 7', 'Item 8', 'Item 9'],
    'Category 20': ['Item 7', 'Item 8', 'Item 9'],
  };

  ngOnInit() {
    // 绑定滚动监听事件
    this.scrollListener = () => this.checkActiveCategory();
    window.addEventListener('scroll', this.scrollListener);
    // 初始化时检查一次激活状态
    this.checkActiveCategory();
  }

  ngOnDestroy() {
    // 移除监听防止内存泄漏
    if (this.scrollListener) {
      window.removeEventListener('scroll', this.scrollListener);
    }
  }

  private checkActiveCategory() {
    const scrollTop = window.scrollY + 80; // 80为分类栏高度,需根据实际样式调整
    let activeCat = '';

    this.categories.forEach(category => {
      const element = document.getElementById(category);
      if (element) {
        const rect = element.getBoundingClientRect();
        // 判断元素是否进入当前视图区域
        if (rect.top <= scrollTop && rect.bottom > scrollTop) {
          activeCat = category;
        }
      }
    });

    if (activeCat !== this.currentActiveCategory) {
      this.currentActiveCategory = activeCat;
    }
  }
}

2. 修改HTML模板

给分类按钮绑定激活样式,同时给页面内容容器添加视图引用:

<div class="category-bar">
  <button 
    *ngFor="let category of categories" 
    (click)="scrollToCategory(category)"
    [class.active]="category === currentActiveCategory"
  >
    {{ category }}
  </button>
</div>

<div class="page-content" #pageContent>
  <div *ngFor="let category of categories" id="{{ category }}">
    <h2>{{ category }}</h2>
    <div *ngFor="let item of items[category]">{{ item }}</div>
  </div>
</div>

3. 添加CSS样式

实现分类栏固定顶部、横向滚动及激活按钮高亮效果:

.category-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  background: white;
  padding: 1rem;
  border-bottom: 1px solid #eee;
  overflow-x: auto;
  white-space: nowrap;
  z-index: 100;
}

.category-bar button {
  margin: 0 0.5rem;
  padding: 0.5rem 1rem;
  border: none;
  background: transparent;
  cursor: pointer;
  transition: color 0.2s;
}

.category-bar button.active {
  color: #165DFF;
  font-weight: bold;
  border-bottom: 2px solid #165DFF;
}

.page-content {
  margin-top: 80px; /* 与分类栏高度一致,避免内容被遮挡 */
  padding: 1rem;
}

/* 给分类区块增加间距,优化滚动体验 */
.page-content > div {
  margin-bottom: 4rem;
  padding: 1rem;
  border: 1px solid #f0f0f0;
}

核心逻辑说明

  • 滚动监听:组件初始化时绑定窗口滚动事件,每次滚动触发激活状态检查
  • 位置判断:通过getBoundingClientRect()获取元素视口位置,结合滚动距离判断当前视图对应的分类
  • 状态同步:点击跳转时直接更新激活状态,滚动时动态计算更新
  • 内存防护:组件销毁时移除滚动监听,避免内存泄漏

内容的提问来源于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.21 11:45:41