使用 cdk-virtual-scroll (Angular 8) 滚动到底部 [英] Scroll to bottom with cdk-virtual-scroll (Angular 8)
问题描述
目标
显示消息列表并在收到新消息时滚动到底部,即使我在顶部也是如此.即使有不同高度的元素,我也想完全滚动到底部.
问题
使用虚拟滚动,我必须设置 [itemSize]
属性,但对我来说它不是静态值:
- 当一条消息对于一行来说太长时,它会分成多行,因此它的高度会发生变化.
- 我有不同类型的不同高度的消息(例如系统消息).
此外,我使用 ng-content
插入来自父级的按钮以加载以前的消息.我看到的是,当 _scrollToBottom
被调用时,它不是把我带到底部,而是把我带到更高一点.我怀疑这是因为 virtual-scroll 中元素的高度不同.
我已经从 Angular 阅读了这个自动调整滚动策略问题:https://github.com/angular/components/issues/10113; 但我不确定这会解决我的问题.
欢迎任何关于我能做什么的想法.
测试
Codesandbox:https://codesandbox.io/s/angular-virtual-scroll-biwn6
- 加载消息后,向上滚动.
- 发送消息.(当新消息加载时,虚拟滚动不再滚动到底部,而是停得更高一点)
- 重复
有错误的视频:https://gofile.io/d/8NG9HD
解决方案
Gourav Garg 给出的解决方案有效.只需执行两次滚动功能即可.
我现在正在这样做:
<预><代码>私人 _scrollToBottom() {setTimeout(() => {this.virtualScrollViewport.scrollTo({底部:0,行为:'自动',});}, 0);setTimeout(() => {this.virtualScrollViewport.scrollTo({底部:0,行为:'自动',});}, 50);}我认为它不是很优雅,但效果很好.
如果你正在使用 cdk 可以使用 >7
this.virtualScrollViewport.scrollToIndex(messages.length-1);
因为这将移动到最后一项的顶部.您需要为该项目调用 scrollIntoView.
this.virtualScrollViewport.scrollToIndex(this.numbers.length - 1);setTimeout(() => {const items = document.getElementsByClassName("list-item");items[items.length - 1].scrollIntoView();}, 10);
<cdk-virtual-scroll-viewport #virtualScroll style="height: 500px" itemSize="90"><ng-container *cdkVirtualFor="让 n 个数字"><li class="list-item">{{n}} </li></ng-容器></cdk-virtual-scroll-viewport>
我已经更新了你的 沙盒
Goal
Display a list of messages and scroll to the bottom when a new message is received, even when I am at the top. I would like to scroll fully bottom even with elements of different heights.
Problem
With virtual scroll, I have to set the [itemSize]
property, but for me it is not a static value:
- When a message is too long for one line it breaks in multiple, so its height changes.
- I have different types of messages with different heights (system messages for example).
Also, I am using ng-content
to insert a button from the parent to load previous messages. What I see is that, when _scrollToBottom
is invoked, instead of taking me to the bottom, it takes me to a bit higher. I suspect this is because of the different heights of elements inside virtual-scroll.
I have read this autosize scroll strategy issue from Angular: https://github.com/angular/components/issues/10113; but I am not sure this will solve my problem.
Any idea of what I could do will be welcome.
Test
Codesandbox: https://codesandbox.io/s/angular-virtual-scroll-biwn6
- When messages are loaded, scroll up.
- Send message. (When the new message is loaded, instead of scrolling to bottom, the virtual-scroll stops a little higher)
- Repeat
Video with the error: https://gofile.io/d/8NG9HD
Solution
The solution given by Gourav Garg works. Simply by executing twice the scroll function.
I am doing this now:
private _scrollToBottom() {
setTimeout(() => {
this.virtualScrollViewport.scrollTo({
bottom: 0,
behavior: 'auto',
});
}, 0);
setTimeout(() => {
this.virtualScrollViewport.scrollTo({
bottom: 0,
behavior: 'auto',
});
}, 50);
}
I think it is not very elegant but works fine.
You can use if you are using cdk > 7
this.virtualScrollViewport.scrollToIndex(messages.length-1);
As this will move to the top of last item. You need to call scrollIntoView for that item.
this.virtualScrollViewport.scrollToIndex(this.numbers.length - 1);
setTimeout(() => {
const items = document.getElementsByClassName("list-item");
items[items.length - 1].scrollIntoView();
}, 10);
<cdk-virtual-scroll-viewport #virtualScroll style="height: 500px" itemSize="90">
<ng-container *cdkVirtualFor="let n of numbers">
<li class="list-item"> {{n}} </li>
</ng-container>
</cdk-virtual-scroll-viewport>
I have updated your sandbox
这篇关于使用 cdk-virtual-scroll (Angular 8) 滚动到底部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!