Title: How to add and remove CSS class n times with setTimeout?
Tags: javascript;jquery;css
Question: I want to add and remove a CSS class n times to show an animation, to show a effect n times, like when you set animation-iteration-count, the diffence is that here I have two animations, the second with delay.
My idea was to use setTimeout, so I read this Stack Overflow post but I didn't get the expected results.
Here is a snippet - and a JSfiddle - with the animation (showing once)
$('button').click(function(){
$('div').addClass('a');
$(this).attr('disabled','true').text('Started');
setTimeout(function(){
$('div').removeClass('a');
$('button').removeAttr('disabled').text('Finished | Again');
},6000);
width: 100px; height: 100px; background: red;
animation: a 2s linear, b 2s 2s linear;
@keyframes a {
from { background: red; }
to { background: blue; }
@keyframes b {
from { background: blue; }
to { background: black; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;</script&gt;
<div&gt;</div&gt;
<button&gt;Start</button&gt;
Comment: @Damon yes, because as I said, I didn't get the expected results. I want to repeat n times a multiple animation and I don't know how to do it. I mentioned 'setTimeout' as an option. What is the best way to do that? Thanks!

Comment: @Damon Can you give an example, please? Thank you

Comment: Unlike `setInterval()`, `setTimeout()` will not repeat and I don't see your `setTimeout` invoking anything that would cause it run more once.

Comment: Can you go into more detail about what you are trying to exactly achieve? If you want a setTimeout to run multiple times (as in the other thread you linked) you have to call it recursively which you are not doing here.

Comment: Use setInterval() and clearInterval(). Basically set up a variable let's say `interval` and set it equal to your `setInterval` function. Have a counter n. After n loops of the interval, call `clearInterval(interval);` (Edit: if you need an example I'll post something in answers - let me know if that works)


Here is another answer: Here is an update to your fiddle:
https://jsfiddle.net/jb03ba1f/2/
As you can see, this will repeat the animation however many times you want, and can also accommodate multiple animations, but it's a little messy. Since you are already using jQuery, I would suggest looking into jQuery's animate API which (I think) has more robust callbacks buuut I hardly use jQuery so you will have to look into that.
If this doesn't cover what you're looking for, maybe you can find an example online to better illustrate your question.
(js / jquery for reference - though I did also update the keyframes to add another animation so look at the fiddle)
$('button').click(function(){
$('div').addClass('a');
$(this).attr('disabled','true').text('Started');
var n = 0;
var interval = setInterval(function() {
$('div').removeClass('a');
if (n === 5) {
clearInterval(interval);
$('button').removeAttr('disabled').text('Finished | Again');
} else {
setTimeout(function() {
$('div').addClass('a');
}, 0)
n++;
}, 4500);

Here is another answer: You can use setInterval and count the number of iterations.
var n = 3;
var iterationCount = 0;
$('button').click(function(){
clearInterval(animInterval);
var animInterval = setInterval(function(){
$('div').toggleClass('a');
iterationCount++;
if (n == iterationCount)
clearInterval(animInterval);
},4000);
https://jsfiddle.net/brhL9h54/10/
Comment for this answer: Thanks, but I must use multiple animations, background-color was an example.

Here is another answer: the css way
Repeating an animation with js seems wrong to me. There is the animation-iteration-count property, and with the possibility off adding multiple @keyframes you should be able to achieve what you are after. For your sample code it is quite simple even (though I suspect your real animation may be a bit different:
animation: a 2s linear 5 alternate;
@keyframes a {
0% { background: red; }
50% { background: blue; }
100% { background: black; }
Feel free to post your actual animation if you can't find a way to achieve it with just css.
https://jsfiddle.net/brhL9h54/4/
the js way
If you insist on going the js way, you'll need to make sure the timeout gets reset after every cycle. This can be done by using calling a function recursively. And with the help of a counter you can easily control how many times you want it to run. Something in this order:
$('button').click(function(){
$('div').addClass('a');
$(this).attr('disabled','true').text('Started');
var counter = 5;
function repeater() {
if (counter &gt;= 0) {
$('div').toggleClass('a');
counter--;
// start new cycle
setTimeout(repeater, 3000);
} else {
// cleanup
$('button').removeAttr('disabled').text('Finished | Again');
// boot the repeater
repeater()
https://jsfiddle.net/brhL9h54/7/
Comment for this answer: Thanks, but I must use multiple animations, background-color was an example
Comment for this answer: That what I meant with my final remark, "Feel free to post your actual animation". Anyways, if you insist on going the js route (which is probably not necessary), I've updated my answer with a possible solution.

Here is another answer: You can handle animationend event. Look at this code:
$('div').on('animationend', function (data) {
if (data.originalEvent.animationName === 'b') {
$('div').removeClass('a');
iteration++;
if (iteration < n) {
setTimeout(function () {  $('div').addClass('a'); });
} else {
iteration = 0;
$('button').removeAttr('disabled').text('Finished | Again');
There is parameter data.originalEvent.animationName which indicates animation name which is ended. Your last animation is b. So then you have to remove class and add it again. You have to also keep somewhere current iteration number and max interations. Check this on here: https://jsfiddle.net/svnwmg3g/

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 5, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2016:00:03/31/16', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<javascript><jquery><css>', 'Title': 'How to add and remove CSS class n times with setTimeout?', 'ViewCount': 1530, 'id': 36344299, 'user_AboutMe': '', 'user_AccountId': 5574794.0, 'user_DisplayName': 'agustin', 'user_Reputation': 1986.0, 'user_Views': 137.0, 'user_id': 4418559.0}}