Topic: Scroll Bottom Of Chat
ewgiddings asked 5 years ago
Expected behavior When adding a new message to the chat component for the chat be aligned to the bottom as happens with most every chat application. Actual behavior Adding a new message does not scroll the overflow to the bottom of the message area. It should auto scroll to the bottom most (newest) message. This is how most chat applications act. Resources (screenshots, code snippets etc.) WhatsApp, Messenger, SMS, all align to the bottom of the overflow when a new message is added.
Question How do we get the MDB Small Chat component of class .my-custom-scrollbar to scroll to the bottom so the newly added messages are in view and push out of view older messages?
Konrad Stępień staff answered 5 years ago
Hi @ewgiddings,
You can use this code for scroll to bottom message:
element.nativeElement.scrollTop = element.nativeElement.scrollHeight;
For example, I get div with @ViewChild
method like this:
HTML:
<div class="my-custom-scrollbar" #scroll>
TS:
@ViewChild('scroll', { static: true }) scroll: any;
and then when I get new message ( ngOnChange or another event) i use this code
this.scroll.nativeElement.scrollTop = this.scroll.nativeElement.scrollHeight;
Can you try this in your project?
Best, Konrad.
ewgiddings commented 5 years ago
Yea this is what I ended up using. I was wondering if this was the way you all recommend since there's nothing in the docs about it.
The biggest problem with this is that pushing a message to the message array and then calling this it only scrolls to the bottom of the message before the newest one. I have to set a timeout on that call of 1 millisecond to actually scroll to the bottom.
this.chatMessages.push({ userName: this.user.userName, userId: this.user.id.toString(), message: this.newMessage }); setTimeout(() => { const messageArea = document.getElementsByClassName('my-custom-scrollbar')[0] as HTMLElement; messageArea.scrollTop = messageArea.scrollHeight - messageArea.clientHeight; }, 1);
If I don't use that setTimeout then the method you described only scrolls to the previously sent message not the newest.
Konrad Stępień staff commented 5 years ago
There are probably other ways to achieve a similar effect, it all depends on how the project is created.
Have you tried maybe to use asynchronous data?
ewgiddings commented 5 years ago
The project is simply pushing a message model into the array of messages using array.push(messageModel). Do you suggest I turn that array push into some sort of promise or async function? Is that what you mean by using async data?
Konrad Stępień staff commented 5 years ago
Do you suggest I turn that array push into some sort of promise or async function?
Yes, but I didn't saw your push
function.
I did your example with this function and I didn't find any other solution besides:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements AfterViewInit {
@ViewChild('scroll', { static: true }) scroll: any;
messages: string[] = [];
addMess = (text: string) => {
this.messages.push(text);
setTimeout(() => {
this.scroll.nativeElement.scrollTo(0, this.scroll.nativeElement.scrollHeight);
}, 0);
};
ngAfterViewInit() {
this.scroll.nativeElement.scrollTo(0, this.scroll.nativeElement.scrollHeight);
}
}
I'm afraid that setTimeout must be used
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: Free
- Premium support: No
- Technology: MDB Angular
- MDB Version: 8.6.0
- Device: Surface
- Browser: Chrome
- OS: Windows
- Provided sample code: No
- Provided link: No