【发布时间】:2019-12-03 18:45:31
【问题描述】:
我正在尝试访问 <div> 元素上的 scrollHeight 和 clientHeight 属性来决定是否显示“查看更多”链接:
<div #clippedContainer class="clipped">
<some-other-component></some-other-component>
<a class="view-more" href="...">View more</a>
</div>
.clipped {
max-height: 600px;
overflow: hidden;
position: relative;
}
.view-more {
position: absolute;
width: 100%;
top: 550px;
text-align: center;
display: none;
.displayed {
display: block;
}
}
@ViewChild('clippedContainer', read: Element)
set clippedContainer(Element container) {
if (container.scrollHeight > container.clientHeight) {
container.querySelector('.learn-more').classes.add('displayed');
}
}
问题是调用时 scrollHeight 为 0,因为组件尚未显示。我尝试在scheduleMicrotask 和ngAfterViewInit 中读取它,但它仍然为0。我发现了一个hack,它等待一秒钟让浏览器计算布局,然后访问所需的属性:
Future.delayed(Duration(seconds: 1)).then(() {
if (container.scrollHeight > container.clientHeight) {
container.querySelector('.learn-more').classes.add('displayed');
}
});
但这会在内容呈现和链接出现之间引入不必要的延迟。有没有更好的方法来检测何时计算了布局并且scrollHeight 和clientHeight 可用?
更新:我发现部分问题在于包含<div> 的组件是由弹出框架动态构建的。看起来像 ngAfterViewInit 这样的钩子甚至在组件附加到 DOM 之前就被执行了。
【问题讨论】:
-
我认为在 ngAfterViewInit 你已经渲染了元素
-
正如我的问题中提到的,我尝试使用
ngAfterViewInit,但它不起作用。在深入挖掘之后,我发现这个组件是由我们使用的弹出框架实例化的。我目前的理论是钩子在附加到 DOM 之前运行。事实上,框架内部使用NgZone.onTurnStart反复检查Element.parent字段何时被设置以确定何时将其添加到DOM。我在NgZone上阅读了一些内容,并计划调查是否可以使用类似的方法,甚至添加一个钩子让弹出框架为我调用它。 -
您能否更新问题以反映这是自定义弹出问题或添加到答案中?
-
发布了更新。我还根据我在弹出框架中找到的代码发布了一个解决方案,但希望有人能找到更好的解决方案。
标签: angular angular-dart