react-infinite-scroller icon indicating copy to clipboard operation
react-infinite-scroller copied to clipboard

LoadMore called on scroll, threshold not taken into account

Open ghost opened this issue 6 years ago • 2 comments

Hello, I have a problem with Chrome and Safari (not with Firefox) : when I scroll, even if I did not reach the threshold yet (250px), the loadMore func is called in Chrome and Safari. In Firefox everything is fine, meaning it's once I have scrolled to the bottom of the parent container that the loadMore func is called.

The parent container has a defined height (I tried in %, vh, px, nothing changes). I'm not using windowScroll.

Any idea ?

Thanks.

[EDIT]: this PR seems to solve the problem: https://github.com/CassetteRocks/react-infinite-scroller/pull/84

ghost avatar Jul 30 '19 07:07 ghost

I have the same problem. Any idea to deal with?

khaphannm avatar Sep 25 '19 07:09 khaphannm

I have the same problem. Any idea to deal with?

Hello, yes, as I couldn't wait for the PR to be merged, I made a custom infiniteScroll by extending the default library and brought the fix in the PR. Here is how it looks like:

import InfiniteScroll from 'react-infinite-scroller/dist/InfiniteScroll';

// Rewrite scroll listener to make infinite scroll threshold detection working on Chrome and Safari
class CustomInfiniteScroll extends InfiniteScroll {
    constructor(props) {
        super(props);
        this.scrollListener = () => {
            var el = this.scrollComponent;
            var scrollEl = window;
            var parentNode = this.getParentElement(el);

            var offset = void 0;
            if (this.props.useWindow) {
                var doc = document.documentElement || document.body.parentNode || document.body;
                var scrollTop = scrollEl.pageYOffset !== undefined ? scrollEl.pageYOffset : doc.scrollTop;
                if (this.props.isReverse) {
                    offset = scrollTop;
                } else {
                    offset = this.calculateOffset(el, scrollTop);
                }
            } else if (this.props.isReverse) {
                offset = parentNode.scrollTop;
            } else {
                // fix is here
                offset = el.parentNode.scrollHeight - el.parentNode.clientHeight - el.parentNode.scrollTop;
            }

            // Here we make sure the element is visible as well as checking the offset
            if (offset < Number(this.props.threshold) && el && el.offsetParent !== null) {
                this.detachScrollListener();
                this.beforeScrollHeight = parentNode.scrollHeight;
                this.beforeScrollTop = parentNode.scrollTop;
                // Call loadMore after detachScrollListener to allow for non-async loadMore functions
                if ('function' === typeof this.props.loadMore) {
                    this.props.loadMore(this.pageLoaded += 1);
                    this.loadMore = true;
                }
            }
        }
    }
}

export default CustomInfiniteScroll;

Then you can use it in place of the default lib:

import CustomInfiniteScroll from './CustomInfiniteScroll';
...
const YourComponent = ({props...}) => {
...
    return (
        <CustomInfiniteScroll .... >...</CustomInfiniteScroll>
    );
};

ghost avatar Sep 25 '19 07:09 ghost