DooDoo
DooDoo

Reputation: 13447

Two consecutive Animation will not run in jQuery

please see this script:

<style type="text/css">
    .div1
    {
        background-color: Aqua;
        width: 400px;
        height: 30px;
    }
    .div2
    {
        background-color: Fuchsia;
        width: 400px;
        height: 30px;
    }
    .div3
    {
        background-color: Green;
        width: 400px;
        height: 30px;
    }
    .div4
    {
        background-color: Orange;
        width: 400px;
        height: 30px;
    }
</style>
<script type="text/javascript">
    $(document).ready(function () {
        var timer = setInterval(showDiv, 2000);

        var counter = 0;

        function showDiv() {
            if (counter == 0) { counter++; return; }
            $('div.My').css('height', '30px');
            $('div.My').animate({ height: '30' }, 2000, function () { alert('i'); });
            $('div.My')
                .stop()
                .filter(function () { return this.id.match('div' + counter); })
                .animate({ height: '50' }, 500, function () { });
            counter == 4 ? counter = 0 : counter++;
        }
    });
</script>
<body>
<div>
    <div class="div1 My" id="div1">
    </div>
    <div class="div2 My" id="div2">
    </div>
    <div class="div3 My" id="div3">
    </div>
    <div class="div4 My" id="div4">
    </div>
</div>
</body>

I want every 5 second my div become large and then become normal and next div become large.The problem is first animation does not run and just second animation run.Where is the problem?

JSFiddle Sample

Edit 1)

I want when next div become large previous div become normal concurrently.Not previous become normal and then next become large

Upvotes: 4

Views: 495

Answers (1)

Austin Mullins
Austin Mullins

Reputation: 7427

Check out my fork of your fiddle and let me know if this is doing what you want. You had a call to .stop() in the middle there, which was blocking the slow shrinking animation from displaying.

Now the full script is:

$(document).ready(function () {
  var timer = setInterval(showDiv, 2000);

  var counter = 0;

  function showDiv() {
     if (counter == 0) { counter++; return; }
     $('div.My').animate({ height: '30px' }, { duration: 500, queue: false });
     $('div.My')
      .filter(function () { return this.id.match('div' + counter); })
      .animate({ height: '50px' }, { duration: 500, queue: false });
     counter == 4 ? counter = 0 : counter++;
  }
});

Edit - new Fiddle

I didn't feel right about the above code, and it didn't work as expected in my browser, so I found a different approach that I think works more cleanly. This one uses jQuery's step option. I also use addClass and removeClass as a kind of local storage to remember which div needs to be shrunk on the next animation. You could do some math with counter and get the same result, but this works.

$(document).ready(function () {
    var timer = setInterval(showDiv, 2000);

    var counter = 0;

    function showDiv() {
       if (counter == 0) { counter++; return; }
       $shrinker = $("div.big").removeClass("big");
       $grower = $("#div"+counter);

       $grower
        .animate({ height:50 },
         {duration:500,
          step: function(now, fx) {
           $shrinker.css("height", 80-now);
          }
         }
        );

      $grower.addClass("big");
      counter == 4 ? counter = 0 : counter++;
    }
});

The step body looks a bit weird, but it guarantees that at each moment of the animation, the total height of the div stack remains constant. Basically, the total height of the shrinking and growing divs (min:30, max:50) has to be 80 at all times, so the height of the shrinking div should be 80 - the height of the growing div.

Upvotes: 2

Related Questions