如何在视口尺寸变化时调整Angular CDK虚拟视口高度?
Angular CDK虚拟视口自动调整高度解决底部空白问题
当视口容器尺寸增大时,CDK虚拟视口不会自动感知高度变化,导致底部出现空白。以下是可行的解决方法:
方法1:通过ResizeObserver监听容器尺寸变化并更新视口
使用浏览器原生的ResizeObserver监听虚拟视口所在容器的尺寸变化,每次变化时手动更新视口高度并触发CDK的视口检查:
import { Component, ViewChild, ElementRef, OnInit, OnDestroy } from '@angular/core'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; @Component({ selector: 'app-root', template: ` <div class="viewport-wrapper" #wrapper> <cdk-virtual-scroll-viewport #virtualViewport itemSize="50"> <div *cdkVirtualFor="let item of itemList" class="list-item"> {{ item }} </div> </cdk-virtual-scroll-viewport> </div> `, styles: [` .viewport-wrapper { width: 100%; height: 100%; } cdk-virtual-scroll-viewport { height: 100%; } .list-item { height: 50px; padding: 0 16px; line-height: 50px; border-bottom: 1px solid #e0e0e0; } `] }) export class AppComponent implements OnInit, OnDestroy { @ViewChild('virtualViewport') virtualViewport!: CdkVirtualScrollViewport; @ViewChild('wrapper') wrapper!: ElementRef<HTMLElement>; itemList = Array.from({ length: 1000 }, (_, idx) => `列表项 ${idx + 1}`); private resizeObserver!: ResizeObserver; ngOnInit(): void { this.resizeObserver = new ResizeObserver(entries => { const { height } = entries[0].contentRect; // 更新视口元素高度 this.virtualViewport.elementRef.nativeElement.style.height = `${height}px`; // 强制视口重新计算可见区域,修复空白 this.virtualViewport.checkViewportSize(); }); this.resizeObserver.observe(this.wrapper.nativeElement); } ngOnDestroy(): void { this.resizeObserver.disconnect(); } }
方法2:确保视口高度继承父容器
不要给cdk-virtual-scroll-viewport设置固定像素高度,而是通过CSS让它继承父容器的高度:
cdk-virtual-scroll-viewport { height: 100%; width: 100%; }
这种方式需要配合方法1的ResizeObserver使用,因为CDK虚拟视口不会自动监听CSS高度的变化,必须手动触发checkViewportSize()来重新计算可见项。
核心原理
CDK虚拟视口默认只会在初始化和窗口滚动时计算可见区域,当容器尺寸通过非窗口resize的方式增大时(比如父容器动态展开),它不会自动更新高度,导致已渲染的列表项数量不足,底部出现空白。通过ResizeObserver监听变化并调用checkViewportSize(),可以强制视口重新计算可见区域,渲染足够的列表项填充空白。
内容的提问来源于stack exchange,提问作者Prasad Tawde
相关产品推荐
相关产品推荐

