我在角度应用程序中有此代码
html :
<input type="button" value="Add" (click)="addItems()" />
<div id="messageContainer" style="width:200px; height:300px; overflow-y:scroll;" #scrollMe >
<div *ngFor="let i of items">
{{i}}
</div>
</div>
component.ts :
items: string[] = [];
count = 20;
@ViewChild('scrollMe') private scrollContainer: ElementRef;
ngOnInit() {
this.addInitialItems();
}
addItems() {
const currentPosition = this.scrollContainer.nativeElement.scrollTop;
this.items.unshift(this.count.toString());
this.count++;
this.scrollContainer.nativeElement.scrollTop = currentPosition;
}
addInitialItems() {
for (let i = 0; i <= this.count - 1; i++) {
this.items.unshift(i.toString());
}
// this is not working
this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
}
最初,messageContainer div应该填充多个项目,并且div滚动到底部,一旦用户单击“添加”按钮,它将在messegaes列表的顶部添加一个项目,并应保持滚动位置。
保留滚动位置是通过
完成的const currentPosition = this.scrollContainer.nativeElement.scrollTop;
//add new item
this.scrollContainer.nativeElement.scrollTop = currentPosition;
但是,最初滚动到div的底部不起作用,
this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
scrollTop
的值即使设置后仍为0,
最初如何使它滚动到div的底部?
答案 0 :(得分:3)
@ViewChild对象才完全定义。尝试将方法调用移到该钩子上。
ngAfterViewInit() {
this.addInitialItems();
}
您可能想尝试的其他方法是直接在模板中绑定到scrollTop,因此您根本不必访问nativeElement。
<input type="button" value="Add" (click)="addItems()" />
<div id="messageContainer" style="width:200px; height:300px; overflow-y:scroll;" [scrollTop]="myScrollVariable">
<div *ngFor="let i of items">
{{i}}
</div>
</div>
然后您可以在组件中简单地编写
this.myScrollVariable = currentPosition;
而不是直接修改DOM元素。当然,如果您想将滚动初始化为scrollHeight,则可能仍然需要使用ViewChild来访问nativeElement并获取该属性(尽管就我个人而言,我只是将scrollTop初始化为一些高得离谱的数字,例如99999999,大于scrollHeight与确切的scrollHeight相同。
如果将方法调用移至ngAfterViewInit无效,请尝试在setTimeout函数中设置scrollTop。有时Angular变化检测器对于获取对本机DOM的更改很奇怪,作为一种变通办法,您可以将更改避开常规角度事件循环并超时。
setTimeout(()=>{ this.scrollContainer.nativeElement.scrollTop = whatever; },1)