The interval is not cleared immediately after repeating for a while

I have a bounce arrow on my website that I created using jquery and setInterval, for example:

bouncing = setInterval(function() { $("div").animate({ top:"30px" },100,"easeInCubic",function() { $("div").animate({ top:"0px" },100,"easeOutCubic"); }); console.log("bounced"); },200); 

You can see it here in the encoder: http://codepen.io/mcheah/pen/wMmowr

I ran it faster than I needed because it is easier to see problems faster. My problem is that after you leave the interval for a few seconds, you will notice that instead of instantly bouncing back or down, the rebound element stops for half a second and then just holds there before starting again. If you leave it to work even longer (20 seconds) and then clear the interval, you will notice that it takes several seconds to stop the jump.

My questions are:

  • Why does a bounce sometimes fail?

  • Why does a clear interval take some time to clear if it repeats for a while?

  • Is there a better way to have a jumping arrow? Are CSS Transitions Improved?

Thank you for your help!

+7
javascript jquery css
source share
4 answers

You are trying to perfectly match the setInterval() timer and the two jQuery animations so that they look perfectly consistent. This requires trouble, and they can slip over time, so it is considered a bad design pattern.

If instead you just use the completion of the second animation to restart the first and do the repetition like this, then you have perfect coordination every time.

You can see it here in a different version of your code: http://codepen.io/anon/pen/NxYeyd

 function run() { var self = $("div"); if (self.data("stop")) return; self.animate({top:"30px"},100, "easeInCubic") .animate({top:"0px"}, 100, "easeOutCubic", run); } run(); $("div").click(function() { // toggle animation var self = $(this); // invert setting to start/stop self.data("stop", !self.data("stop")); run(); console.log("toggled bouncing"); }); 
+3
source share
  • It is not recommended to mix animate() with timers this way. There is NO chance that you can sync something like this. And there is no need. You can simply add the function to the animation queue, look here: fooobar.com/questions/834956 / ...

  • What animate() does is put the animation request in the job queue, which will be processed later when the time is right. When you break the interval, the material that accumulates in the queue will still be processed. There is a way to clear the queue and immediately stop the entire animation.

  • JQuery's animation functions actually control CSS, and there is nothing behind it in HTML. Another option is to use the canvas, but this is a completely different approach, and I would not recommend it. With jQuery animations, you already have a better choice.

This is a simple solution to your problem:

 function bounce() { $("div") .animate({ top: "30px" }, 100, "easeInCubic") .animate({ top: "0px" }, 100, "easeOutCubic", bounce); // this loops the animation } 

Start bouncing on page load with

 $(bounce); 

Stop bouncing when pressed:

 $("div").click(function() { $("div").stop().clearQueue().css({ top: "0px" }); // you want to reset the style because it can stop midway }); 

EDIT: Some inaccuracies have been fixed. The following is an example of codepen execution.

+1
source share

If you want to use javascript for animation, you can use something better, like http://greensock.com/docs/#/HTML5/GSAP/TweenMax/to/ something like this:

 var tween = TweenMax.to($("div"), 100, {y: "100px", yoyo: true, repeat: -1}); 
0
source share

You can enclose the interval code with:

 if(!$("div").is(":animated")) 

This will only lead to animation if your previous one is finished. The reason this was weird is because your animations are queued. You can check how it works now: http://codepen.io/luminaxster/pen/XKzLBg

I would recommend using a full callback when the second animation ends and has a variable to control the recursive failure call in this version:

http://codepen.io/luminaxster/pen/qNVzLY

0
source share

All Articles