Ionic Scroll Bottom ?*

This works for me. But I had to change how to initialize the Content.

@ViewChild(Content) content: Content;

Source:

1 Like

Yeah this works.
check this out by @smukov

I am getting the error
"[ts] Property 'scrollBottom' does not exist on type ContentDimensions" .The properties of dimensions are as below:

 {
  "contentHeight": 465,
  "contentTop": 64,
  "contentBottom": 49,
  "contentWidth": 325,
  "contentLeft": 0,
  "scrollHeight": 465,
  "scrollTop": 0,
  "scrollWidth": 325,
  "scrollLeft": 0
}
1 Like
import { ViewChild } from '@angular/core';
import { Content } from 'ionic-angular';

export class Chat {

  @ViewChild(Content) content: Content;

  constructor( ) {    }
  ionViewDidLoad(){
    let dimensions = this.content.getContentDimensions();
    this.content.scrollTo(0, dimensions.scrollHeight+100, 100);
  }
  ionViewDidEnter() {
    let dimensions = this.content.getContentDimensions();
    this.content.scrollTo(0, dimensions.contentHeight+100, 100);
  }
}
1 Like

please give me a full refe code

The same can be done using .scrollTop, .scrollHeight present in JavaScript.
They are use to get scrolled position for a particular element.

Usage -

    var myElement = document.getElementById('my-element');  // Container which has scrollable vertical contents
    myElement.scrollTop;  // Gives scrolled poins from top
    myElement.scrollHeight;  // Gives maximum scrollable vertical space

    myElement.scrollTop = myElement.scrollHeight;  // Setting the top scroll value to maximum allowed value

For animated scrolling -

	$('body,html').animate({ scrollTop: 0}, 800);

I am using ngAfterViewChecked(). Mine code structure is -

home.html -

<ion-content padding>
    <div #scrollMe id="messages-container" style="overflow: auto; height: 100%;">
        // All messages elemets. Scroll
    </div>
</ion-content>

home.ts -

import { Component,ViewChild, AfterViewChecked, * * } from '@angular/core';
.
.
export class HomePage implements OnInit, AfterViewChecked{
    // used for scrolling the pane
    @ViewChild('scrollMe') private myScrollContainer: ElementRef;

    ngAfterViewChecked() {
        this.scrollToBottom();
    }

    scrollToBottom(): void {
        // method used to enable scrolling
        this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
    }
}

Bonus - In case you have “Load More messages” button for chat app, within scrollToBottom(), you can write conditions to calculate previous height of container. But keep that variable global.

OR -

home.html -

<ion-content #scrollMe padding style="overflow: auto; height: 100%;">
    <div id="messages-container">
        // All messages elemets. Scroll
    </div>
</ion-content>

home.ts -

import { Component,ViewChild, AfterViewChecked, * * } from '@angular/core';
.
.
export class HomePage implements OnInit, AfterViewChecked{
    // used for scrolling the pane
    @ViewChild('scrollMe') private myScrollContainer: ElementRef;

    ngAfterViewChecked() {
        this.scrollToBottom();
    }

    scrollToBottom(): void {
        // methods used to enable scrolling
        var elemObj:any = this.myScrollContainer;
        if(this.clickedLoadMore.clicked && this.clickedLoadMore.data_added){
          // If load more was clicked and data is available
          elemObj.scrollTo(0, elemObj.getContentDimensions().scrollHeight - this.oldChatHeight, 0);
          this.updatePreviousMessagesSize();
        }
        else if(this.messages.length > this.previousMessagesSize){
          // If new message has came in messages array
          elemObj.scrollToBottom();
          this.updatePreviousMessagesSize();
        }
    }
}

I have included my codes where I am comparing my previous message height with the new one to maintain current view when new messages loads after clicking on Load More button.

I have calculated this.oldChatHeight in other part of overall code which is -

this.oldChatHeight = elemObj.getContentDimensions().scrollHeight;

Notice I have used ElementRef in @ViewChild('scrollMe') private myScrollContainer: ElementRef instead of Content which is an alternate of the way mentioned in Ionic document

3 Likes

Whether in typescript or plain JavaScript following should work. it is simple. Try it out:

        var element = document.querySelector('#giveAnIdToTopElementForExampleContentOrWhatever');
        console.log(element);
        element.scrollIntoView();

For scrollIntoView support, check MDN documentation or following list take from MDN.

Capture

Thanks a lot! Works perfectly well! Great Job!

Btw, in iOS the scroll refreshes every second or so, and when I scroll up, it automatically refreshes and scrolls the view to the bottom again, over and over again. Any idea how to fix this? Thanks!

1 Like

I am not sure what is hapening in your case on iOS. Have you implemented counter in your app which updates view or something which monitors scrolling and updates view?
I can’t say if my app has same issue in iOS (its stucked due to “NSApp Transport Security” because of http).

I followed Angular life hooks to implement this feature. I tried to replace ngAfterViewChecked() with other checks, but didn’t worked for me. Try other hooks to see if any works for you.

You can also try mutation observer to check for changes in DOM.

If none of above solutions work, we can try to find a way of using ngZone to limit scope/elementes for change detections.

In my 2nd suggested answer(the OR part), I am comparing height of content container with its previous height.
I think you can use this to prevent unwanted scrolls.

The ngAfterViewChecked() gets called even on touch/click event. May be this could be reason that your app is auto scrolling while scrolling.

I’ve learned a few things when it comes to autoscrollers;

• Never auto scroll from your back-end;
• Never put autoscrollers in setIntervals();
• They’re nearly impossible without a badass framework like Ionic.

I’ve been working on a chat app in Ionic V1 for 2 1/2 years and no autoscrollers works as good as it does using it with sockets.

My recommendation for anyone to ever see this post; use Ionic V2+ and Socket.io then use your socket to operate the content scrolling mechanism when needed.

I know this may be like “wow kid” to some of the elite master Ionic Devs, but it’s a tip for the intermediate/simi advanced Ionic Devs.

Regards,
Neonic1

There’s a CSS solution for this that works way smoother.

I was running into the same issues, and trying to solve it with .scrollToBottom() and timeouts and whatnot. the solution was passable at best. But definitely not great.

This answer did it for me. For Ionic 3, I just added this to the css of the page:

.scroll-content {
    overflow: auto;  /* redundant, but just in case */
    display: flex; /* redundant, but just in case */
    flex-direction: column-reverse;
}

Be sure to have a div inside your <ion-content> that contains all the other content, otherwise your content will be ordered in reverse.

2 Likes

I’ve not had a moment to study flex or the grids yet. I’ve fooled with them a little when they were released, they seem very complex… But, they seem bad ass. Great tip! :smiley:

It moves towards the bottom of the page.But my requirement is to enable scrolling from top to bottom automatically when the page loads…?

How can i achieve that…?

I have tried all above solutions…but no use…

Requesting help .thanks

great solution, thanks!

this.content.scrollToBottom();

wow…thanks alot…i tried the above methods using content.scrollbottem .but they condradict with virtual scrolling feature in ionic.anyway thanks to you now everythings fine.

setTimeout(() => {

      this.content.scrollToBottom(200);

    }, 100);