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

Angular 4如何获取*ngIf隐藏组件的高度?附StackBlitz示例

解答你的Angular组件高度获取问题

首先明确说:通过OnInit钩子无法获取被*ngIf隐藏的组件高度。因为当*ngIf条件为false时,Angular根本不会渲染这个组件,对应的组件实例都没被创建,OnInit钩子自然不会触发,也就无从获取高度了。

那点击按钮显示组件后,怎么获取高度呢?这里有几种可靠的方法:


方法一:利用ViewChild + setTimeout(简单直接)

Angular修改DOM需要一定时间,点击按钮切换*ngIf条件后,DOM不会立即完成更新,用setTimeout可以让浏览器先完成渲染,再去获取高度:

父组件(控制显示的组件)代码示例:

import { Component, ViewChild } from '@angular/core';
import { ChildCompo } from './child.component';

@Component({
  selector: 'app-parent',
  template: `
    <button (click)="showChild = true">显示子组件</button>
    <child-comp *ngIf="showChild" #childRef></child-comp>
  `
})
export class ParentComponent {
  showChild = false;
  @ViewChild('childRef') childComponent!: ChildCompo;

  // 也可以直接在按钮点击事件里处理
  onShowChild() {
    this.showChild = true;
    setTimeout(() => {
      const height = this.childComponent.getHeight();
      console.log('子组件高度:', height);
    }, 0);
  }
}

子组件代码修改:

给子组件添加一个获取高度的方法,通过ElementRef拿到自身DOM元素:

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

@Component({
  selector: 'child-comp',
  templateUrl: './child.component.html'
})
export class ChildCompo {
  constructor(private el: ElementRef) {}

  getHeight(): number {
    // offsetHeight包含padding、border,clientHeight只包含padding,按需选择
    return this.el.nativeElement.offsetHeight;
    // 或者用 return this.el.nativeElement.clientHeight;
  }
}

方法二:使用ChangeDetectorRef + AfterViewChecked(更贴合Angular机制)

如果不想用setTimeout,可以借助Angular的变更检测机制,在DOM更新完成后再获取高度:

import { Component, ViewChild, ChangeDetectorRef, AfterViewChecked } from '@angular/core';
import { ChildCompo } from './child.component';

@Component({
  selector: 'app-parent',
  template: `
    <button (click)="showChild = true">显示子组件</button>
    <child-comp *ngIf="showChild" #childRef></child-comp>
  `
})
export class ParentComponent implements AfterViewChecked {
  showChild = false;
  @ViewChild('childRef') childComponent!: ChildCompo;
  private hasFetchedHeight = false; // 避免重复执行

  constructor(private cdr: ChangeDetectorRef) {}

  ngAfterViewChecked() {
    if (this.showChild && !this.hasFetchedHeight) {
      // 手动触发变更检测,确保DOM已完成更新
      this.cdr.detectChanges();
      const height = this.childComponent.getHeight();
      console.log('子组件高度:', height);
      this.hasFetchedHeight = true;
    }
  }
}

方法三:子组件内部监听自身渲染完成

如果想让子组件自己获取高度并处理,可以用AfterViewInit钩子——只有当*ngIf条件为true、组件完成渲染后,这个钩子才会触发:

import { Component, ElementRef, AfterViewInit, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child-comp',
  templateUrl: './child.component.html'
})
export class ChildCompo implements AfterViewInit {
  @Output() heightReady = new EventEmitter<number>();

  constructor(private el: ElementRef) {}

  ngAfterViewInit() {
    const height = this.el.nativeElement.offsetHeight;
    console.log('子组件自身高度:', height);
    // 也可以把高度通过事件传给父组件
    this.heightReady.emit(height);
  }
}

父组件接收高度:

<button (click)="showChild = true">显示子组件</button>
<child-comp *ngIf="showChild" (heightReady)="onChildHeightReady($event)"></child-comp>
onChildHeightReady(height: number) {
  console.log('从子组件拿到的高度:', height);
}

总结一下:

  • *ngIf隐藏时组件未被渲染,OnInit钩子完全无法获取任何相关信息;
  • 组件显示后,必须等DOM更新完成再获取高度,推荐用ViewChild配合setTimeout,或者用Angular原生的变更检测+生命周期钩子,也可以让子组件自己监听渲染完成事件。

内容的提问来源于stack exchange,提问作者ttmt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:46:59