Reputation: 59
I am Developing App in ionic. when load page scrollToBottom not working.
Html section
<ion-content #content>
</ion-content>
TS Section
@ViewChild(Content) content: Content;
ionViewDidLoad() {
console.log('ionViewDidLoad PersonalChatPage');
this.content.scrollToBottom();
}
Upvotes: 1
Views: 6194
Reputation: 1473
don't use the garbage scrolling methods from your framework I have the same problem with framework ionic, instead use standard .scrollIntoView() it works nicely...
I set up two dummy hidden divs, top and bottom around my "content" like so
<div id="QV_Top">TOP</div>
... your actual content here
<div id="QV_Bottom">BOTTOM</div>
then fixed my scroll helper methods like so:
finally the actual scroll to id follows:
Upvotes: -1
Reputation: 2347
The problem is that the scrollToBottom()
code may run before the DOM is completely updated.
Several solutions based on reacting to DOM/Template to execute the scrolling can be tried.
The best one that i have found was in this article by josh Morony
To resume it: One could use a Mutation Observer to execute the scroll only when a certain DOM event has triggered.
Here is some code to illustrate it.
// To get Typescript completion for Ionic 4 use:
// import { IonContent } from '@angular/core'
// @ViewChild(Content) contentArea: IonContent;
@ViewChild(Content) contentArea: Content;
// list in the template to observe
@ViewChild(List, {read: ElementRef}) chatList: ElementRef;
// MutationObserver doesn't need to be imported
private mutationObserver: MutationObserver;
ionViewDidLoad(){
// Code to be executed on event
this.mutationObserver = new MutationObserver((mutations) => {
this.contentArea.scrollToBottom();
});
// the Element that will be Observed
this.mutationObserver.observe(this.chatList.nativeElement, {
childList: true
});
}
More info about Mutation Observer at Mozilla. Its browser compatibility is very good.
I haven't personally tried it, but another very interesting alternative can be found in this answer by mhartington from the Ionic Team.
Here is the code:
<ion-content>
<ion-list>
<ion-item *ngFor="let item of items; let last = last">
{{ item }}
{{ last ? callFunction() : '' }}
</ion-item>
</ion-list>
</ion-content>
export class Page2 {
public items: any[] = [];
@ViewChild(Content) content: Content
constructor(
public navCtrl: NavController,
public navParams: NavParams) {
setTimeout(() => {
for (let i = 0; i < 100; i++) {
this.items[i] = i
}
}, 300)
}
callFunction(){
this.content.scrollToBottom(0)
}
}
So the idea is to call this.content.scrollToBottom()
only once the last item is created on the template. Using index, this would give the power to automatically scroll to any of the elements, although i don't see the use at this moment.
As for the argument that it isn't good to directly manipulate the DOM in Angular: There is no manipulation, just reacting in the component to a DOM event...
Upvotes: 1
Reputation: 12022
Adding a delay will fix your issue.
ionViewDidLoad() {
console.log('ionViewDidLoad PersonalChatPage');
let that = this;
setTimeout(()=>{that.content.scrollToBottom();},200);
}
And another thing as your code has #content tag like below:
<ion-content #content></ion-content>
Then you can write like:
@ViewChild('content') content: Content;
Upvotes: 10