Angular 13.3.10无限滚动求助:实现加载组件而非图片的功能
Angular 13.3.10 手动实现组件无限滚动方案
既然ngx-infinite-scroll没达到预期,直接手动实现更可控,以下是针对加载组件的无限滚动实现步骤:
1. 基础配置与模板结构
先在组件中定义核心变量,模板里渲染列表组件和加载提示:
组件类初始代码
import { Component, HostListener, OnInit, OnDestroy } from '@angular/core'; @Component({ selector: 'app-infinite-scroll', templateUrl: './infinite-scroll.component.html', styleUrls: ['./infinite-scroll.component.css'] }) export class InfiniteScrollComponent implements OnInit, OnDestroy { // 列表数据 itemList: any[] = []; // 当前页码 currentPage = 1; // 每页条数 pageSize = 10; // 是否正在加载 isLoading = false; // 是否已加载全部数据 hasMore = true; ngOnInit(): void { // 初始化加载第一页数据 this.loadMore(); } ngOnDestroy(): void { // 组件销毁时可清理滚动监听(window监听用HostListener会自动处理,自定义容器监听需手动移除) } }
模板代码
<!-- 滚动容器,需设置固定高度/最大高度 + overflow:auto --> <div class="scroll-container"> <!-- 渲染自定义组件,这里用app-item作为示例 --> <app-item *ngFor="let item of itemList" [itemData]="item"></app-item> <!-- 加载提示 --> <div class="loading-tip" *ngIf="isLoading">加载中...</div> <div class="no-more-tip" *ngIf="!hasMore && !isLoading">已加载全部</div> </div>
样式代码
.scroll-container { max-height: 600px; /* 根据需求设置高度 */ overflow-y: auto; } .loading-tip, .no-more-tip { text-align: center; padding: 16px; color: #666; }
2. 实现滚动触底检测
通过监听滚动事件,判断是否到达加载阈值:
方式一:监听window滚动(适合整页滚动场景)
在组件类中添加HostListener:
@HostListener('window:scroll', []) onWindowScroll(): void { if (this.isLoading || !this.hasMore) return; // 计算滚动位置 const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; const clientHeight = document.documentElement.clientHeight || document.body.clientHeight; const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight; // 距离底部200px时触发加载 if (scrollTop + clientHeight >= scrollHeight - 200) { this.loadMore(); } }
方式二:监听自定义容器滚动(适合局部滚动场景)
如果是容器内滚动,需要获取容器元素并监听scroll事件:
import { ElementRef, ViewChild } from '@angular/core'; // 在组件类中添加 @ViewChild('scrollContainer') scrollContainer!: ElementRef<HTMLDivElement>; private scrollListener?: () => void; ngOnInit(): void { this.loadMore(); // 绑定容器滚动监听 this.scrollListener = () => this.onContainerScroll(); this.scrollContainer.nativeElement.addEventListener('scroll', this.scrollListener); } ngOnDestroy(): void { // 移除监听 if (this.scrollListener) { this.scrollContainer.nativeElement.removeEventListener('scroll', this.scrollListener); } } onContainerScroll(): void { if (this.isLoading || !this.hasMore) return; const container = this.scrollContainer.nativeElement; // 计算容器滚动位置 if (container.scrollTop + container.clientHeight >= container.scrollHeight - 200) { this.loadMore(); } }
同时修改模板,给容器添加模板引用:
<div #scrollContainer class="scroll-container"> <!-- 列表内容 --> </div>
3. 实现数据加载逻辑
编写loadMore方法,模拟或调用真实接口加载数据:
loadMore(): void { this.isLoading = true; // 模拟接口请求,替换为你的真实API调用 setTimeout(() => { // 生成模拟数据 const newItems = Array.from({ length: this.pageSize }, (_, i) => ({ id: (this.currentPage - 1) * this.pageSize + i + 1, content: `组件内容 ${(this.currentPage - 1) * this.pageSize + i + 1}` })); // 合并数据到列表 this.itemList = [...this.itemList, ...newItems]; this.currentPage++; // 模拟没有更多数据的情况(比如加载到第5页就停止) if (this.currentPage > 5) { this.hasMore = false; } this.isLoading = false; }, 1000); }
关键注意事项
- 滚动容器必须设置固定高度/最大高度和
overflow: auto,否则无法触发scroll事件。 - 加
isLoading状态防止重复触发加载,避免接口多次请求。 - 根据实际场景选择window滚动或容器内滚动的监听方式。
- 如果列表项高度不固定,触底判断的阈值可以适当调大,提升用户体验。
内容的提问来源于stack exchange,提问作者It's Bender
相关产品推荐
相关产品推荐

