powegu2006
powegu2006

Reputation: 9

function firing multiple times when scrolling fast

First of all, I'm not very advanced at code and tend to only do this part time so please excuse all terrible/ugly code! I appreciate there are already some solutions out there but I can't seem to make any of them work with my code so would really appreciate some help!

I'm using isotope grid and trying to setup an infinite scroll. I want to load 10 images at a time when the user scrolls to the bottom by taking these images from an array and appending them to a temp div.

This is working perfectly when scrolling slowly, but as soon as you scroll quickly the function seems to fire multiple times, it gets a little glitchy and loads lots of images at once.

$(window).scroll(function() {

var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
var docuHeight = $(document).height();

if(scrollTop + windowHeight == docuHeight){

  nextTenImages = imagesData.splice(0,10);
  var content = ""
  for (var i = 0; i < nextTenImages.length; i++) {
      content +=
      "<div class='box " + nextTenImages[i]["type"] + "'" + ">" +
        "<div class='box-wrapper'>" +
          "<img src='" + nextTenImages[i]["src"] + "' />" +
        "</div>" +
      "</div>"
  };

  $('body').append('<div id="temp-load"><div id="grid"></div></div>');
  $('#temp-load > #grid').append(content)

  $('#temp-load > #grid').children().css({
      opacity: 0
  });

  var toAdd = $('#temp-load > #grid').html();

  $container.isotope('insert', $(toAdd), function(){
    $container.children().css({
      opacity: 1
    });
    $('#temp-load').remove();
  });

}

});

Upvotes: 0

Views: 1300

Answers (2)

user5066707
user5066707

Reputation:

Make a single timeout to run the callback. This may avoid the function from executing multiple times.

var timer;

function scrollEvt() {
    /* scroll actions */
}

$(window).scroll(function() {
    /* clear the old timeout */
    clearTimeout(timer);
    /* wait until 400 ms for callback */
    timer = setTimeout(scrollEvt, 400);
});

Using other ways may result in problems (like comparing (window.performance || Date).now())...

Upvotes: 1

Iceman
Iceman

Reputation: 6145

Unbind that specific scroll event till your delayed operation is completed to prevent accumulating more of the event triggers which create the duplication behaviour as in your case.

var winCached = $(window),
  docCached = $(document)

var currLeng = 0;

function addContent() {
  dettachScrollEvent();
  setTimeout(function() { //this timeout simulates the delay from the ajax post
    for (var i = currLeng; i < currLeng + 100; i++)
      $('div').append(i + '<br />');
    currLeng = i;
    console.log("called loader!");
    attachScrollEvent();
  }, 500);

}

function infiNLoader() {
  if (winCached.scrollTop() + winCached.height() > docCached.height() - 300) {
    addContent();
    //alert("near bottom! Adding more dummy content for infinite scrolling");
  }
}

function attachScrollEvent() {

  winCached.scroll(infiNLoader);
}

function dettachScrollEvent() {
  winCached.unbind('scroll', infiNLoader);
}
addContent();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>

Upvotes: 0

Related Questions