0

I am using this function to delay adding animation class to items when they come in to view.

$(function() {
  var itemQueue = [];
  var queueTimer;

  function processItemQueue() {
    var $delay = 100; // needs to be based on item data-delay attr
    if (queueTimer) {
      return;
    }

    queueTimer = window.setInterval(function() {
      if (itemQueue.length) {
        var $firstinque = $(itemQueue.shift());
        var $animation = $firstinque.attr('data-effect');

        $firstinque.addClass($animation);

      } else {
        window.clearInterval(queueTimer);
        queueTimer = null;
      }
    }, $delay);
  }

  $(".item-animate").waypoint(function() {
    itemQueue.push(this.element);
    processItemQueue();
  }, {
    offset: '90%'
  })
});

FIDDLE

Base function works fine but I need to set the delays based on items data-delay attribute and I cant do that within the setInterval. Please see the fiddle above for more info. The second item in the fiddle has delay of 500ms, so it should fire later. Any help is appreciated.

Benn
  • 4,840
  • 8
  • 65
  • 106
  • 3
    Possible duplicate of [Changing the interval of SetInterval while it's running](http://stackoverflow.com/questions/1280263/changing-the-interval-of-setinterval-while-its-running) – Sebastian Simon Mar 26 '16 at 20:13
  • You cannot change the time value of a setInterval or setTimeout once defined -- all you can do is to cancle it and recreate it. – Soren Mar 26 '16 at 20:13
  • 1
    Rather than using setInterval which is supposed to use a fixed delay and repeat, string together a bunch of setTimeouts, which only trigger once with a fixed delay. – James Mar 26 '16 at 20:15
  • @James do you mind showing an example? – Benn Mar 26 '16 at 20:33
  • if you look at console of `http://jsfiddle.net/tg5op333/2/` you will see the order of calling the function and you will see the second item with delay of 3000 will be added with that delay but at the end because for other intervals with less amount of time it animates and adds them . if you would like the second item shows at its right place you need to pause calling next item until second delay is passed. – Matin Kajabadi Mar 26 '16 at 21:00
  • @Matt.k not bad but the staggering effect is gone and it must than be set different for each item inside the data attr, the idea is to delay the effect for each new item by specific delay. – Benn Mar 26 '16 at 21:12

1 Answers1

1

Since every item gets called by (waypoint) fairly at the same time you need to increase the data-delay attribute in your sequence of items based on specific delay you want to have for that items. here I am increasing by 200
HTML:

<div id="container">
 <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="200"></div>
  </div>
  <!-- anim end -->
 <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="400"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="600"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="800"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="1000"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="1200"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="1400"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="1600"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="1800"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="2000"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="200"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="400"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="600"></div>
  </div>
  <!-- anim end --> <!-- anim -->
  <div class="item">
    <div class="item-in item-animate" data-effect="show" data-delay="800"></div>
  </div>
  <!-- anim end -->


</div>


JS:

$(function() {
  var itemQueue = [];

  function processItemQueue() {
      if (itemQueue.length) {
        var $firstinque = $(itemQueue.shift());
        var $animation = $firstinque.attr('data-effect');
        $firstinque.addClass($animation);
      } 

  }

  $(".item-animate").waypoint(function() {
    itemQueue.push(this.element);
    var delay = $(this.element).data('delay');
    setTimeout(function(){
       processItemQueue();
    }, delay);
  }, {
    offset: '90%'
  })
})

Example : http://jsfiddle.net/tg5op333/5/

Matin Kajabadi
  • 3,414
  • 1
  • 17
  • 21
  • not bad , but the second row of items is delayed to much, they should restart from 200 again and that is why i had that previous function. – Benn Mar 26 '16 at 22:15
  • for the second row which I think is the last four items, you can simply set it from 200 again and increase it for that sequence of items which gets called later – Matin Kajabadi Mar 26 '16 at 22:24