Search code examples
javascriptangularjsdom-eventsaddeventlistenerinfinite-scroll

Why is my EventListener getting called twice?


In my Angular mobile app (Ionic framework), I'm setting up my infinite scroll functions. It's basically the same code as the dashboard version yet my scrollTagsPanel gets called twice.

getTagsFactory Inside my getTagsFactory I do an API call and retrieve back tag objects, then I pass the tags into the getTagsColHeight function inside of tagsPanelDirective:

tagsPanelCtrl.tagsPanel.totalTags = data.data.ticker_tags_rows;
tagsPanelCtrl.tagsPanel.tagsLoaded = true;
tagsPanelCtrl.tagsPanel.getTagsColHeight(tagsPanelCtrl.tagsPanel.tags);

tagsPanelDirective

Here are the only 2 methods responsible for the infinite scroll. getTagsColHeight checks to make sure that the tags array is not empty, then it simply adds the event scroll to the function scrollTagsPanel.

The calculation to determine if the height of the tags column tagsCol has reached a point that matches it's height is in scrollTagsPanel.

function getTagsColHeight(tags) {
    if (tags.length != 0 || tags.length != undefined) {
        $timeout(function() {
            tagsCol.addEventListener('scroll', scrollTagsPanel);
        });
    }
}

function scrollTagsPanel(event) {
    // Reached bottom of tags panel:
    console.log('tagsCol height: ', tagsCol.offsetHeight);
    console.log('scrolled point: ',(tagsCol.scrollHeight - tagsCol.scrollTop));

    if ((tagsCol.scrollHeight - tagsCol.scrollTop) === tagsCol.offsetHeight) {
        if (!vm.limitReached) {

            vm.start += vm.limit;
            vm.tagsLoaded = false;

            if ((vm.start + vm.limit) > vm.totalTags) {
                vm.limitReached = true;
                console.log('vm.limitReached = true!', vm.limitReached);
            }

            console.log('scrollTagsPanel...');
            loadTags();
        }
    }
}

What scroll step produces 2 calls with the exact same data:

enter image description here

I console.log(event) and I see 1 Event {} and 1 CustomEvent {}, does this help?

enter image description here


UPDATE - ok I can get the event to first just once if I click on the column, so I guess it's detecting a click and scroll at the same time when I scroll?

Below, I scrolled once, and then clicked twice afterwards:

enter image description here


Solution

  • var timeout;
    
    tagsCol.addEventListener('scroll', function () {
        clearTimeout(timeout);  
        timeout = setTimeout(function() {
            scrollTagsPanel();
        }, 50);
    });
    

    According to: https://stackoverflow.com/a/22018607/636478


    Adding the AngularJS version:

    tagsCol.addEventListener('scroll', function () {
        $timeout.cancel(vm.scrollEventTimer);
        clearTimeout(vm.scrollEventTimer);
        vm.scrollEventTimer = $timeout(function() {
            scrollTagsPanel();
        }, 50);
    });