设置nativeElement.scrollTop不起作用,滚动到div的底部

时间:2018-07-10 16:23:37

标签: html angular

我在角度应用程序中有此代码

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的底部?

1 个答案:

答案 0 :(得分:3)

直到'ngAfterViewInit'生命周期钩子之前,

@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)