Ionic - How to determine if scroll is at the botto

2019-04-15 14:23发布

问题:

I have some chat functionality in my app where when a new message is entered, it automatically scrolls to the bottom of the <ion-content>, however, like many chat applications, if you're scrolled up in the chat to read something previous to the latest message, I'd like to NOT scroll. Only when the user is at the very bottom of the screen, would I like to scroll to the bottom, once the new message comes in. I have yet to solve this issue.

Here is my current code:

scrollToBottom() {

  // If the scrollTop is greater than the height, we are at the bottom,
  // in which case, show scrolling animation
  let dimensions = this.content.getContentDimensions();
  let scrollHeight = dimensions.scrollHeight;
  let scrollTop = dimensions.scrollTop;
  let contentHeight = dimensions.contentHeight;
  let heightAndScrollTop = contentHeight + scrollTop;

  // This is the best I can get, assuming that the screen is in a consistent dimension, which we all know is basically non-existent due to all the different types of screens
  if((scrollHeight - heightAndScrollTop) <= 39 && (scrollHeight - heightAndScrollTop) >= 0) { 
    this.content.scrollToBottom(300);
  }
}

Any idea what I can do to solve this?

回答1:

First, create an element at the bottom of your content:

<ion-content>
    //Your messages go here
    ...
    <div id="check-point"></div>  <-- Notice this element
</ion-content>

Second, write a function to detect whether check-point element is fully in viewport (viewable area) or not. You can easily find a function in SO. Here is a simple one:

   //This function just check if element is fully in vertical viewport or not
   isElementInViewPort(element: HTMLElement,  viewPortHeight: number) {
      let rect = element.getBoundingClientRect(); 
      return rect.top >= 0  && (rect.bottom <= viewPortHeight);
   }

Finally, Whenever you push a new message, check if check-point is in viewport. If yes, it means user is in bottom of page. If no, it means user is not.