如何获得 Angular 5 组件元素的位置?
Posted
技术标签:
【中文标题】如何获得 Angular 5 组件元素的位置?【英文标题】:How can I get an Angular 5 component element's position? 【发布时间】:2018-09-13 03:35:01 【问题描述】:在一个 Angular 5 组件中,我有一个 table,我需要创建一些东西,比如在多个 td 之上叠加多个 div .获得这些 td 在表格中的位置以便我可以定位其他元素的最佳方法是什么?
我目前正在尝试使用类似的东西
@ViewChild('table')
tableElement: ElementRef
ngAfterViewChecked()
this.tableElement.nativeElement.getElementsByClassName('cell')
// ...
但我这样做是冒着一些奇怪的无限循环的风险。例如,有没有办法知道特定元素被“重绘”了?
【问题讨论】:
【参考方案1】:“无限”循环是正常的,因为您在 AfterViewChecked 生命周期挂钩中运行该函数。
按设计:AfterViewChecked Lifecycle hook that is called after every check of a component's view.
我会使用 getBoundingClientRect
来获取顶部、底部、宽度、高度等。const domRect = element.getBoundingClientRect();
https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect,但我不确定我是否理解在哪种情况下要运行 getElement。 “重绘”是什么意思?如果数据是动态的,你可以尝试在 promise 解决后获取位置。
【讨论】:
我想要一个事件或类似的东西,在绘制表格后调用 get 并且我可以获得每个元素的位置,所以我可以以某种方式定位覆盖的 div。 正如我在回答中提到的,如果表的数据来自后端,则在解决承诺时必须调用 getBoundingClientRect()。如果表格的数据在模板中被硬编码,那么 ngAfterViewInit() 应该没问题。它只被调用一次。【参考方案2】:据我了解,您希望相对于另一个元素(div)定位一个 html 元素(td)。这似乎是一个普通的 html 和 css 问题。
您可以将这两个元素放在一个包含框中
position: relative;
您要放置在上面的 div 应该具有以下属性,以便它们与您的 td 重叠
position: absolute;
top: /*your top value*/;
left: /*your left value*/;
如果你真的想得到你的 td 的确切位置,那么你需要通过 javascript 提取顶部、底部、右侧和左侧的位置。
this.tableElement.nativeElement.getElementsByClassName('cell').getBoundingClientRect();
【讨论】:
我在定位DIV时没有TD的位置,所以不是CSS问题。 您不需要 td 的位置来相应地定位 div。或者使用我在下面提到的选项。【参考方案3】:一种方法:合并来自调整大小事件和主题的流。如果您使用 http 获取数据而不是主题,则可以使用从那里已经拥有的相同 observable,例如 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();
编辑:
将这个问题转移到您将在这些 TD 中使用的组件可能是一种更简洁、更简单的解决方案。您可以使用ng-content
显示组件内的任何内容,并通过在构造函数中注入它来获取 elementRef。如果您仍然需要与父母交谈,请使用输出。
【讨论】:
【参考方案4】:这里提出的方法对我不起作用。相反,我使用了getBoundingClientRect
和window.innerHeight
。
从boundingRect
,添加顶部和高度属性。如果小于window.innerHeight
,则变为可见。
此方法适用于任何框架 (afaik)。但这是一个 Angular 示例:
import ElementRef from '@angular/core';
class ExampleComponent
constructor(private el: ElementRef)
window.addEventListener('scroll', () =>
const rect = this.el.nativeElement.getBoundingClientRect();
if (rect.top + rect.height < window.innerHeight)
console.log('component is visible');
);
【讨论】:
以上是关于如何获得 Angular 5 组件元素的位置?的主要内容,如果未能解决你的问题,请参考以下文章
Angular 5:从组件访问元素内部 html 以获取动态生成的元素