Reputation: 29349
I am using twitter bootstrap in my app. I have a requirement to animate an icon every 20 seconds.
Here is the code i have. Its in coffee script. But its very basic and can easily be related to javascript.
@updateCountIndicator = () ->
data = Math.floor (Math.random() * 10) + 1
countIndicator = $("#count-indicator")
countIcon = $("#count-icon")
countIcon.removeClass("icon-animated-vertical")
countIndicator.html data
countIcon.toggleClass "icon-animated-vertical"
timedCountUpdate()
@timedCountUpdate = () ->
setTimeout(updateCountIndicator, 20000)
The problem is, icon animates the first time(20 seconds after page refresh). But doesn't animate after that. It works properly when i debug using breakpoints. Am i doing something wrong here?
Upvotes: 1
Views: 785
Reputation: 434685
I think I (finally) see the problem. We'll look at your fiddle:
$(document).ready(function(){
setTimeout(animateIcon, 20000);
});
function animateIcon() {
$("#change-color").addClass("animate-color");
setTimeout(animateIcon, 20000);
}
and go from there. Each time animateIcon
is called, it will:
$("#change-color").addClass("animate-color");
But that does nothing if #change-color
already has the animate-color
class so you only see the animate-color
animation once. That would lead us to try this CoffeeScript version:
animateIcon = ->
$('#change-color').removeClass('animate-color')
$('#change-color').addClass('animate-color')
setTimeout(animateIcon, 20000)
$(animateIcon)
That looks like it should re-add the animate-color
class and re-trigger the CSS animation but it won't. Why not? Well, the second time that animateIcon
runs, #change-color
will have animate-color
at the beginning of the function and it will have animate-color
at the end when the browser gets control again; since #change-color
's classes haven't changed (i.e. it will have the same classes before and after), nothing will happen.
To get around that problem, you need to sort of trick the browser into thinking that the classes have actually changed. One way to get that to happen goes like this:
#change-color
.animate-color
.So how do we hand control back to the browser? A setTimeout(..., 0)
call is a common trick for that. Converting the above to CoffeeScript gives us:
addClassAndRestart = ->
$('#change-color').addClass('animate-color')
setTimeout(animateIcon, 20000)
animateIcon = ->
$('#change-color').removeClass('animate-color').css('background', 'transparent')
setTimeout(addClassAndRestart, 0)
$(animateIcon)
The .css('background', 'transparent')
may or may not be needed but that's what #change-color
starts with so I added it.
Demo: http://jsfiddle.net/ambiguous/BByJD/
Sorry about the delay, I lost track of this question.
Upvotes: 3