How can I get an Angular 5 component element's position?

懵懂的女人 提交于 2021-01-28 08:59:22

问题


In an angular 5 component I have a table, and I need to create something like overlaying multiple divs above several td's. What's the best way to get the position of those td's in the table so I can position the other elements?

I'm currently trying to use something like

@ViewChild('table')
tableElement: ElementRef

ngAfterViewChecked() {
    this.tableElement.nativeElement.getElementsByClassName('cell')
    // ...
}

But I'm risking some weird infinite loops doing it this way. Is there a way to know that a specific element was "redrawn", for instance?


回答1:


The "infinite" loop is normal cause you run the function in the AfterViewChecked lifecycle hook.

By design : AfterViewChecked Lifecycle hook that is called after every check of a component's view.

I would use getBoundingClientRect to get top, bottom, width, height etc. const domRect = element.getBoundingClientRect(); https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect, but I am not sure I understood which in which event you want to run the getElement. What do you mean by "redrawn" ? You can try to get the position after promise is been resolved if the data is coming dynamically.




回答2:


As far as I understand you want to position an html element (the td) relative to another (the div). This seems to be a plain html and css issue.

You could position both elements in a containing box with

position: relative;

And the div that you want to position above should have following properties so that they overlap with your td

position: absolute;
top: /*your top value*/;
left: /*your left value*/;

If you really want to get the exact position of your td then you need to extract the top, bottom, right and left position via Javascript.

    this.tableElement.nativeElement.getElementsByClassName('cell').getBoundingClientRect();



回答3:


One way: merge a stream from resize events and a subject. Instead of a subject, if you're fetching the data with http you could use the same observable you already have from there, like http.get(...).pipe(share())

import {merge} from 'rxjs/observable/merge';
import {fromEvent} from 'rxjs/observable/fromEvent';
import {Subject} from 'rxjs/Subject};
// ...
tableChange$:Subject<void> = new Subject();

ngOnInit() {
    merge(
         fromEvent(window, 'resize'),
         this.tableChange$
    ).subscribe(() => {
        this.tableElement.nativeElement.getElementsByClassName('cell')...
    }); // remember to unsubscribe this subscription at OnDestroy in real life
    this.tableChange$.next();
}

Edit:

It might be a cleaner & simpler solution to move this concern to a component you'd use inside those TDs. You can use ng-content to show whatever content inside the component, and get an elementRef by injecting it in the constructor. And if you still need to talk to the parent, use outputs.



来源:https://stackoverflow.com/questions/49636332/how-can-i-get-an-angular-5-component-elements-position

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!