6

I have a problem with animate loop. There is an object i want to move in a special way and do it in loop. Are there any native options to make it? I have this:

$(function () {
    function runIt() {
        $('#div').show("slow");
        $('#div').animate({"marginLeft":"300px"},8000);
        $('#div').animate({"marginLeft":"0px"},8000);
        $('#div').hide("slow", runIt);
    }
    runIt();
});

But it seems not so pretty.

3
  • Looks pretty good to me. kingjiv's answer with the indentation makes it look even better. Commented Jun 14, 2011 at 13:58
  • kingjiv's solution looks a likely candidate, the only thing I would add to it is consideration of the 'onComplete' function allowed within the animate function. Look at jQuery Api Docs for more info! Commented Jun 14, 2011 at 14:00
  • I added a link in my answer to an old fiddle of mine where I use a small plugin and custom queues. Hope it helps! :) Commented Jun 14, 2011 at 14:17

2 Answers 2

17

That's the proper way to queue animations. However, there's some things that can be made to your code to make it a bit snappier and prettier:

  • Store a reference to the selected element in a local variable to speed up execution (less queries made to the DOM)
  • Clean it up by removing unnecessary quotes for object properties
  • Sizing is measured in pixels per default so we can use pure integers instead
  • The named function can be replaced with a immediately invoked anonymous function and then use arguments.callee as the callback

Here's an example showcasing the above changes:

$(function () {
    var element = $("#div");
    (function(){
        element
            .show("slow")
            .animate({ marginLeft: 300 }, 1000)
            .animate({ marginLeft: 0 },   1000)
            .hide("slow", arguments.callee);
    }());
});

You can also do it in a more advanced way by creating your own plugin to use custom queues. I created a small fiddle a while back when I was fooling around with animation queues.

More about immediately invoked function expression can be read on Ben "Cowboy" Alman's blog.

Sign up to request clarification or add additional context in comments.

1 Comment

in a more generic case one may call arguments.callee(); as a separate line
16

That is how I would do it. The only suggestion I would make is to use chaining for nicer code and so the jquery object doesn't get created every time.

$(function () {
   function runIt() {
      $('#div').show("slow")
               .animate({"marginLeft":"300px"},8000)
               .animate({"marginLeft":"0px"},8000)
               .hide("slow", runIt);
   }

   runIt();
});

9 Comments

thanks for your suggestion. but is there any other way to do the same thing more pretty without using callback-hack?
Craptastic! We had the same idea ;)
It's not a hack, in my opinion it's the best way to do it. When the animation is complete you start it again. The only other way that I can think of is setTimeout or setInterval, but that's much uglier. You'd have to figure out how long your animation runs and set the timeout to that... ugly.
thanks, that all i want to know. i thought may be jquery has something special for loop animate, but this option works for me good.
@AlexFord No it won't. It's not true recursion. The call to runIt completes. The next call to runIt is called as a callback to hide and at that time the first runIt is done and off the stack.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.