Deepak Kumar
Deepak Kumar

Reputation: 59

Content Scroll to Bottom Not Working

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

Answers (3)

Meryan
Meryan

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: enter image description here

finally the actual scroll to id follows: enter image description here

Upvotes: -1

user3658510
user3658510

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.

First Solution

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.

Second Solution

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

Setu Kumar Basak
Setu Kumar Basak

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

Related Questions