Leon Gaban Leon Gaban - 1 month ago 6
Javascript Question

Why is my Scroll event being called twice here?

enter image description here

InfiniteScrollFactory:

const scrollingSocial = (e) => {
console.log('scrollingSocial');
// e.stopPropagation();
const reachedBottom = () => socialCol.scrollHeight - socialCol.scrollTop === socialCol.offsetHeight;
const loadMoreItems = () => {
console.log('[ Fire Once ] loadMoreItems...');
$rootScope.$emit("socialmedia.stream.load");
};
if (reachedBottom()) loadMoreItems();
};

const wireSocialScroll = (list) => {
console.log('wireSocialScroll called!');
if (notEmpty(list)) {
socialCol.addEventListener('scroll', scrollingSocial);
}
};

const attachScrollListener = (location, col, list) => {
console.log('attachScrollListener');
console.log(' location', location);
switch (location) {
// case 'tagsPanel' : tagsCol = col; wireTagsScroll(list); break;
// case 'feedPanel' : feedCol = col; wireFeedScroll(list); break;
case 'socialMedia' : socialCol = col; wireSocialScroll(list); break;
}
};


My
scrollingSocial
function gets called once when I scroll down the mouse once. It takes about 45 'scrolls' to finally trigger my
loadMoreItems
function. However then it gets called twice. And I see the scroll the 46th time even though I did not scroll a 46th time.

socialMediaDirective:

const getColHeight = (tags) => {
if (notEmpty(tags)) InfiniteScrollFactory.attachScrollListener('socialMedia', socialCol, tags);
};

Answer

Scrolling and it's even triggers can be a bit finicky.

Just using this code:

$(document).on('scroll', () => console.log('scroll'));

I get multiple scrolls each time I tick my mouse wheel, no matter how carefully I do so.

It's probably the same sort of issue with what you have. What you'll want to do is simply add a boolean that keeps track of if you've called loadMoreItems, use that boolean to keep it from calling it again.

let loadingMoreItems = false;
const scrollingSocial = (e) => {
    console.log('scrollingSocial');
    // e.stopPropagation();
    const reachedBottom = () => socialCol.scrollHeight - socialCol.scrollTop === socialCol.offsetHeight;
    const loadMoreItems = () => {
        console.log('[ Fire Once ] loadMoreItems...');
        $rootScope.$emit("socialmedia.stream.load");
    };
    if (!loadingMoreItems && reachedBottom()) {
        loadingMoreItems = true;
        loadMoreItems();
    }
};

Then, at an appropriate time (or times), change that boolean back to false to allow it to call again (scrolling back up, more items loaded, reachedBottom() resulting in false once, etc).