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

如何在视口尺寸变化时调整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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 15:39:36