Angular 17中ng-bootstrap Scrollspy实现单次仅显示激活图片
Angular 17 + ng-bootstrap Scrollspy 实现单图切换显示
问题说明
使用ng-bootstrap Scrollspy组件时,右侧ngbScrollSpy容器内的所有图片同时显示,需要实现滚动时仅展示当前激活导航项对应的图片,其余隐藏,匹配预期效果。
解决方案
1. 组件类添加激活状态跟踪
在home.component.ts中引入NgbScrollSpy,监听激活事件并保存当前激活的片段ID:
import { Component, ViewChild } from '@angular/core'; import { NgbScrollSpy } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.scss'] }) export class HomeComponent { @ViewChild('s') scrollSpy!: NgbScrollSpy; activeFragment: string | null = null; ngAfterViewInit() { this.scrollSpy.activeChange.subscribe(fragment => { this.activeFragment = fragment; }); } }
2. 修改模板控制图片显示
更新home.component.html,给每个标题和图片包裹独立容器,通过*ngIf判断是否匹配当前激活ID,同时调整Scrollspy容器结构确保每个片段占满容器高度:
<!-- How it Works START --> <div class="container"> <div class="row how-it-works justify-content-between align-items-center"> <div class="col-12"> <h2>How it works</h2> <p>See how our products make it easy for you</p> </div> <div class="col-5"> <nav class="navbar px-3 mb-3"> <ul class="nav nav-pills" [ngbScrollSpyMenu]="s"> <li class="nav-item"> <div class="nav-link" ngbScrollSpyItem="basic-1"> <div class="title">Grab our product</div> <p> Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. </p> </div> </li> <li class="nav-item"> <div class="nav-link" ngbScrollSpyItem="basic-2"> <div class="title">Activate product & build profile</div> <p> Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. </p> </div> </li> <li class="nav-item"> <div class="nav-link" ngbScrollSpyItem="basic-3"> <div class="title">Share & connect</div> <p> Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. </p> </div> </li> <li class="nav-item"> <div class="nav-link" ngbScrollSpyItem="basic-4"> <div class="title">Save contact & turn into leads</div> <p> Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. </p> </div> </li> </ul> </nav> </div> <div class="col-5"> <div ngbScrollSpy #s="ngbScrollSpy" class="scrollspy-container text-center" style="height: 400px"> <div class="scrollspy-fragment" ngbScrollSpyFragment="basic-1"> <h4>01</h4> <img src="https://placehold.co/400x350" alt="Image" *ngIf="activeFragment === 'basic-1'" /> </div> <div class="scrollspy-fragment" ngbScrollSpyFragment="basic-2"> <h4>02</h4> <img src="https://placehold.co/400x350" alt="Image" *ngIf="activeFragment === 'basic-2'" /> </div> <div class="scrollspy-fragment" ngbScrollSpyFragment="basic-3"> <h4>03</h4> <img src="https://placehold.co/400x350" alt="Image" *ngIf="activeFragment === 'basic-3'" /> </div> <div class="scrollspy-fragment" ngbScrollSpyFragment="basic-4"> <h4>04</h4> <img src="https://placehold.co/400x350" alt="Image" *ngIf="activeFragment === 'basic-4'" /> </div> </div> </div> </div> </div> <!-- How it Works END -->
3. 调整样式确保片段占满容器
更新home.component.scss,给每个片段设置100%高度,确保滚动时每个片段能触发激活状态:
.how-it-works { @extend .pt-5; @extend .pb-5; .navbar { .nav-pills { .nav-item { width: 100%; border-bottom: 1px solid $gray-500; &:last-child { border-bottom: 0px; } .nav-link { padding: 12px 0; &.active { background-color: transparent; .title { color: $primary; } p { display: block; color: $dark; margin-bottom: 0; } } .title { font-size: $fs-lg; font-weight: 500; color: $dark; } p { display: none; } } } } } .scrollspy-container { position: relative; overflow-y: auto; .scrollspy-fragment { height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; } } }
效果说明
- 滚动右侧容器时,当前激活导航项对应的图片自动显示,其余图片隐藏
- 点击左侧导航项时,右侧会滚动到对应片段并展示匹配图片
内容的提问来源于stack exchange,提问作者Siddhesh Shedge
相关产品推荐
相关产品推荐

