Reputation: 3067
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
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:
Upvotes: 3