4lackof
4lackof

Reputation: 1400

AJAX - Delay time between displaying AJAX results

I have a search feature which uses an AJAX request to get data from my web-server.

I want to have a fade in animation which gets applied to each search result, with a slight delay so the last result fades in last (i.e. the first result loads, starts fading in, next one loads, starts fading in, etc.).

I have the code which loads the html into the search results area, but it seems like the results are displaying and running their "fade-in-animation" at the same time - although this could also be due to the fact that my computer is too slow.

Here's me code:

JS

$.ajax({
  type: 'GET',
  url: '/PersonSearch',
  data: {
    'search_value': search
  },
  dataType: 'json',
})
.done(function(json) {
  $('#main').html('');
  $.each(json, function(key, value) {
    var search = $('<div />', {
       id: 'search' + key,
       'class': 'search-item off',
       html: 
        '<div class="basic-info">' +
          '<span class="first-name">' + value.First_name + '</span>' +
          '<span> </span>' +
          '<span class="last-name">' + value.Last_name + '</span>' +
        '</div>' +
        '<div class="dropdown">' +
          '<span class="phone-number">' + 'PHONE: ' + value.Phone_number + '</span>' +
          '<span class="email">' + 'EMAIL: ' + value.Email_address + '</span>' +
          '<div class="box edit"><img src="../media/gear.svg"/></div>' +
        '</div>'
    }).appendTo('#main');
    setTimeout(function() {
      search.removeClass('off');
    });
  });
});

CSS

.search-item.off{
  opacity: 0;
  top: 8px;
}
.search-item{
  overflow: hidden;
  position: relative;
  opacity: 1px;
  top: 0;
  transition: .75s;
}

HTML

<div id="main">

</div>

Basically what the code does (so you do not need to piece it together yourself) is it adds the search result which has the class of search-item off, and once the <div> is loaded (using setTimeout()) it removes the off class, which then uses the transition CSS attrib to make it fade in over time.

I tried using setTimeout() on the .appendTo('#main') but that did not work.

I need it so that there is a delay in posting each of the search results in the #main element so that there is a delay in running the fade in animation.

Upvotes: 0

Views: 813

Answers (4)

zoom
zoom

Reputation: 1756

Your idea could work, but you need to add a little delay to your call to setTimeout. The delay must be increased for each new result. To be sure that it is working, use a long delay at first (1000, ie. 1 second) then adjust with lover values as desired.

setTimeout(function() { ... }, 1000 * index);

Below is a simple snippet that illustrate the use of setTimeout to delay the successive calls to append

$(function() {
  var $container = $('#container');
  $.each(['foo', 'bar', 'qux'], function(i, value) {
    setTimeout(function() {
      $container.append('<div>' + value + '</div>');
    }, 1000 * i);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
</div>

Upvotes: 2

Brice
Brice

Reputation: 950

Try using the timeout in the callback of the $.each() function.

$.each(json, setTimeout(function(key, value) {...},1000) )

Upvotes: 0

lchabrand
lchabrand

Reputation: 165

try use

setTimeout(function() { ... }, 0);

It will wait that your content is fully loaded.

Upvotes: 2

Fma
Fma

Reputation: 362

This happens because setTimeout works asynchronously which means these setTimeout functions will start at 5ms, 10ms, 13ms, etc. and fire off at similar times as well. What you can do is define a timeout variable above ajax call and increase timeout at each call before setTimeout and give this timeout variable as the timeout value to the setTimeout. Following is an example (I know too much timeout):

var timeout = 0;
$('div').each(function() {
  var $this = $(this);
  timeout += 1000;
  setTimeout(function() {
    $this.hide('slow');
  }, timeout);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>

Upvotes: 1

Related Questions