JCvanDamme
JCvanDamme

Reputation: 671

Calling getBoundingClientRect() on element returns object with zero values

I have a simple ionic 5.31.1 / Angular 11.1.0 web app where I place a div (inner div) inside another div (outer div). I want to access the position of the inner div relative to the outer div from the code. Calling getBoundingClientRect() to the inner div returns an object where top, bottom, left, right, x and y are all 0.

Here is the code

app.component.ts

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

import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { DomController } from '@ionic/angular';


@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent implements AfterViewInit {

  constructor(
    private readonly platform: Platform,
    private readonly splashScreen: SplashScreen,
    private readonly statusBar: StatusBar, 
    private readonly domCtrl: DomController
  ) {
    this.initializeApp();
  }

  @ViewChild('box') 
  private box: ElementRef;


  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();
    });
  }
  
  
  async ngAfterViewInit() {
    await this.domCtrl.read(() => {
      console.log(this.box.nativeElement.getBoundingClientRect()); // <-- returns { top: 0, bottom: 0, ... }
    });
  }
}

app.component.html

<ion-app>
  <div class="outer-box">
    <div #box class="inner-box"></div>
  </div>
</ion-app>

app.component.scss

.outer-box {
  background: yellow;
  height: 100%; 
  display: flex; 
  align-items: center; 
  justify-content: center;
}

.inner-box {
  position: relative; 
  background: blue; 
  width: 50px; height: 50px;
}

Upvotes: 0

Views: 2037

Answers (1)

misha1109
misha1109

Reputation: 378

Try using Angulars AfterContentChecked lifecycle since you are projecting your html to the component

  ngAfterContentChecked() {
    if (this.box) {
      await this.domCtrl.read(() => {
        console.log(this.box.nativeElement.getBoundingClientRect());
      });
    }
  }

And just for a test try to add a setTimeout function inside the life cycle hook and only then getBoundingClientRect(), perhaps the element havent been fully rendered when you are checking it

Upvotes: 1

Related Questions