So I want to add a class to each element in a list(specifically the <a>
in the list items), but one at a time. I am doing this because the <a>
have a CSS transition on them and I want to have them animate one at a time. So item1 animates, then item2 animates, then item3 animates... Here is what I could attempt to e up with so far.
html:
<ul>
<li><a>item1</a></li>
<li><a>item2</a></li>
<li><a>item3</a></li>
</ul>
jQuery/js:
animateItems();
function animateItems(){
$('ul li a').each(function() {
$(this).addClass('animate'); //This doesn't run one at a time
});
}
I feel like this is leading in the direction of recursion, but not sure really.
update: I just realized that this may be harder than i thought because jQuery needs to know about the css transition time doesnt it? Is there a way to add the classes with a setTimeout() until it begins the next addClass()? Does each() create an array or jQuery object that I can iterate through?
So I want to add a class to each element in a list(specifically the <a>
in the list items), but one at a time. I am doing this because the <a>
have a CSS transition on them and I want to have them animate one at a time. So item1 animates, then item2 animates, then item3 animates... Here is what I could attempt to e up with so far.
html:
<ul>
<li><a>item1</a></li>
<li><a>item2</a></li>
<li><a>item3</a></li>
</ul>
jQuery/js:
animateItems();
function animateItems(){
$('ul li a').each(function() {
$(this).addClass('animate'); //This doesn't run one at a time
});
}
I feel like this is leading in the direction of recursion, but not sure really.
update: I just realized that this may be harder than i thought because jQuery needs to know about the css transition time doesnt it? Is there a way to add the classes with a setTimeout() until it begins the next addClass()? Does each() create an array or jQuery object that I can iterate through?
Share Improve this question edited Mar 26, 2015 at 1:24 chasethesunnn asked Mar 26, 2015 at 1:19 chasethesunnnchasethesunnn 2,2345 gold badges27 silver badges43 bronze badges 2- 1 You can read the transition attribute using JS to adjust the delay accordingly. – Alex Commented Mar 26, 2015 at 1:27
- @mvp I didnt know that this could be done. thanks! – chasethesunnn Commented Mar 26, 2015 at 1:51
4 Answers
Reset to default 10You could use the setTimeout
function:
$('ul li a').each(function(i, el) {
setTimeout(function() {
$(el).addClass('...');
}, i * 1000);
});
The above code assumes that the CSS animation duration is 1s. You can change it accordingly!
And a note: this
in the context of the setTimeout
callback function doesn't refer to the current element. You should either cache the this
object of the each
callback or use the second parameter of the each
callback which refers to the current element in the set.
Why not put the animation duration in a variable and use setTimeout
?
var animationDuration = 2000; // 2000 millieseconds
function animateItems(){
$('ul li a').each(function(i, item) {
setTimeout(function(){
$(item).addClass('animate');
}, i * animationDuration); // this multiplies the index by the duration so the handler is fired in sequence
});
}
Another option would be to use the JavaScript Animation Events.
in javascript, you'll usually use the setTimeout and setInterval functions when you want to schedule code to be run in the future, but there are no blocking instructions like "Thread.Sleep"
animateItems();
function animateItems(){
$('ul li a').each(function(i) {
setTimeout(function(){
console.log(i);
$(this).addClass('animate'); //This doesn't run one at a time
}, i * 1000);
});
}
getElementsByClassName can make an HTMlCollection which cannot be directly iterated with for/in loops, but foreach loop for HTMLCollection elements may provide some insight. To turn the HTMLCollection into an array, reference here. Unfortunatly I'm not familiar with these collections and can't say much.
After you have an array iterating over them should be easy. Apply each animation, including setTimeout.