admin管理员组

文章数量:1323336

I am trying to delay waypoint for every next item by 0.2s. I tried with set timeout but by the time the first few items load the timeout has already expired.

Fiddle 1

$(function() {

  $(".item").each(function(index, element) {
    var $this = $(this);

    var $delay = $(this).data('delay');
    setTimeout(function() {

      $this.waypoint(function() {

        $(this.element).addClass('show');

      }, {
        offset: '90%',
      });

    }, $delay);


  });

});

Than I tried adding the delays inside the waypoint but the last items get longer delays since they are not in the view

$(function() {

  $(".item").each(function(index, el) {

    new Waypoint({
      element: el,
      handler: function() {
        var element = $(this.element),
          delay = element.attr('data-delay');
        setTimeout(function() {
          element.addClass('show');
        }, delay);
        this.destroy();
      },
      offset: '90%'
    });

  });

});

Fiddle 2

any help is appreciated.

I am trying to delay waypoint for every next item by 0.2s. I tried with set timeout but by the time the first few items load the timeout has already expired.

Fiddle 1

$(function() {

  $(".item").each(function(index, element) {
    var $this = $(this);

    var $delay = $(this).data('delay');
    setTimeout(function() {

      $this.waypoint(function() {

        $(this.element).addClass('show');

      }, {
        offset: '90%',
      });

    }, $delay);


  });

});

Than I tried adding the delays inside the waypoint but the last items get longer delays since they are not in the view

$(function() {

  $(".item").each(function(index, el) {

    new Waypoint({
      element: el,
      handler: function() {
        var element = $(this.element),
          delay = element.attr('data-delay');
        setTimeout(function() {
          element.addClass('show');
        }, delay);
        this.destroy();
      },
      offset: '90%'
    });

  });

});

Fiddle 2

any help is appreciated.

Share Improve this question asked Mar 3, 2016 at 13:18 BennBenn 5,0238 gold badges67 silver badges111 bronze badges 5
  • Unless I'm missing what you're trying to do, Fiddle 1 works perfectly for me (in Chrome 48.0.2564.116 m) – Ageonix Commented Mar 3, 2016 at 13:23
  • 1 @Ageonix , works ok for the first items in view , when you scroll the rest of them appear without the delay, they just fade in, instead each to wait 0.2s and than fade in – Benn Commented Mar 3, 2016 at 13:24
  • @PapaSmurf, no bud , each item must delay by 0.2s once in view – Benn Commented Mar 3, 2016 at 13:27
  • Ah I see what you mean now. I doubled the amount of DIV's you have in the Fiddle and it made it easier to see the issue. – Ageonix Commented Mar 3, 2016 at 13:28
  • Ok, the handler function is called immediately, if you run the script and immediately scroll down the page you can see that last item was showed after 1600ms. – Matteo Codogno Commented Mar 3, 2016 at 13:31
Add a ment  | 

2 Answers 2

Reset to default 8

In order to create this staggered effect without knowing how many items will be in view and trying to do all the acrobatics described in other answers and ments, you can instead use the waypoint to feed a queue and process items in that queue at your staggered interval. This is true in general, not just for animation and not just for Waypoints.

$(function() {
  var itemQueue = []
  var delay = 200
  var queueTimer

  function processItemQueue () {
    if (queueTimer) return // We're already processing the queue
    queueTimer = window.setInterval(function () {
      if (itemQueue.length) {
        $(itemQueue.shift()).addClass('show');
        processItemQueue()
      } else {
        window.clearInterval(queueTimer)
        queueTimer = null
      }
    }, delay)
  }

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

Fiddle

The second fiddle you have will work BUT you have to take a few things into account:

  1. How many items will be visible immediately when the browser loads? These items will need to have delays that are 200ms apart (e.g. 200, 400, 600, 800).
  2. Any additional items that will only be visible upon scrolling will need to start back at 200ms in terms of scroll delay. Take for example your jsfiddle where as you scroll through 2 new item Waypoints are triggered at a time. These will need to again be 200ms apart (200, 400, 200, 400, etc.). In other words, each 'row' needs to start back at 200ms and increment by 200 until it reaches the end of the row.

    <div id="container">
      <div class="item" data-delay="200">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="400">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="600">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="800">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="200">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="400">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="200">
        <div class="item-in"></div>
      </div>
      <div class="item" data-delay="400">
        <div class="item-in"></div>
      </div>
    </div>
    

See this adaptation of your second fiddle.

本文标签: javascriptHow to delay jQuery Waypoint for each item in order to create staggering effectStack Overflow