Amit Patil
Amit Patil

Reputation: 3067

React scroll to bottom only works for the first time (demo inside)

I have a react project where I am trying to implement infinite scroll, But not sure why it detects bottom only once, from next time onwards there is always 1 pixels difference in values so it never matches with element.clientHeight

Below is code that I am using to detect scroll to bottom

Math.ceil(element.scrollHeight - element.scrollTop) === element.clientHeight

Going forward I actually want to fire axios call 200 pixels before it reached to bottom so In the mean time I can fetch the data and append to bottom so user never have to wait for data to load.

I have created demo repo which has the same issue as my project CodeSandbox demo

Upvotes: 2

Views: 559

Answers (1)

PlugNPlay
PlugNPlay

Reputation: 261

element.scrollTop - how many scrolled from top, element.scrollHeight - element's whole scroll height (with content visible and invisible), element.offsetHeight - current visible height

When scrolling down, scrollTop increases,

So you want to scroll down to the bottom, in other words you want distance(height) moved from top plus height of element's visible part to be equal to whole element's height:

element.scrollTop + element.offsetHeight = element.scrollHeight

we can write this as:

element.scrollTop = element.scrollHeight - element.offsetHeight

So if you want some action happen before reaching the bottom, just substract this amount of pixels from element.scrollHeight, for example for 200px:

element.scrollTop = (element.scrollHeight - 200) - element.offsetHeight

or like this to make it work even after we pass the distance:

element.scrollTop >= element.scrollHeight - element.offsetHeight - 200

Aditionally, as using scroll inside element (div) with ref, you probably want to add event listener to scrollRef.current, not window

componentDidMount() {
  this.loadList();
  this.scrollRef.current.addEventListener("scroll", this.handleScroll, true);
}

and remove event listener on unmount

componentWillUnmount() {
  this.scrollRef.current.removeEventListener("scroll", this.handleScroll);
}

This should work:

CodeSandbox demo

Upvotes: 3

Related Questions