【问题标题】:Setting nativeElement.scrollTop is not working, to scroll to bottom of div设置 nativeElement.scrollTop 不起作用,滚动到 div 的底部
【发布时间】:2022-03-17 11:01:28
【问题描述】:

我在 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 滚动到底部,一旦用户单击 Add 按钮,它会将一个项目添加到 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 的底部?

【问题讨论】:

    标签: html angular


    【解决方案1】:

    @ViewChild 对象在 'ngAfterViewInit' 生命周期钩子之前没有完全定义。尝试将您的方法调用移至该钩子。

    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 的更改很奇怪,作为一种解决方法,您可以通过超时将更改转义到常规 Angular 事件循环之外。

    setTimeout(()=>{ this.scrollContainer.nativeElement.scrollTop = whatever; },1)
    

    【讨论】:

    • 不需要setTimeout。只在 ngAfterViewInit 中设置 scrollTop 的一部分。在 ngOnInit/constructor 中设置初始模型值。 stackblitz.com/edit/angular-5pm6ks?file=src/app/…
    • 你很可能是对的,但是某些 DOM 属性/方法在 Angular 中是有限的,有时我必须将它们置于超时状态,以便它们会不断变化(想到 .focus())
    【解决方案2】:

    要构建已接受的答案,您可以使用模板变量非常优雅地设置一个 div 以在底部开始滚动:

    <div class="overflow-scroll" #scrollContainer [scrollTop]="scrollContainer.scrollHeight">
    <!-- tall/wide content -->
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-01
      • 2016-11-29
      • 2014-12-22
      • 1970-01-01
      • 2023-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      相关资源
      最近更新 更多