I am currently working on a site where I have a bunch of tiles "fly in" to the screen. I need to add a class to each tile on a delay so they come in one after another. I have the following code that works, but if I want to add more tiles, I will have to edit the jQuery each time.
Is there a way to trim this script down so I don't have to manually add new animations to the new tiles?
function tilesAnimation() {
setInterval(function () {
$("ul.homepageTabs li").eq(0).css("display", "inline-block");
$("ul.homepageTabs li").eq(0).addClass('animated fadeInDown');
$(".loader").fadeOut();
}, 1800);
setInterval(function () {
$("ul.homepageTabs li").eq(1).css("display", "inline-block");
$("ul.homepageTabs li").eq(1).addClass('animated fadeInDown');
}, 2100);
setTimeout(function () {
$("ul.homepageTabs li").eq(2).css("display", "inline-block");
$("ul.homepageTabs li").eq(2).addClass('animated fadeInDown');
}, 2400);
setTimeout(function () {
$("ul.homepageTabs li").eq(3).css("display", "inline-block");
$("ul.homepageTabs li").eq(3).addClass('animated fadeInDown');
}, 2700);
setTimeout(function () {
$("ul.homepageTabs li").eq(4).css("display", "inline-block");
$("ul.homepageTabs li").eq(4).addClass('animated fadeInDown');
}, 3000);
setTimeout(function () {
$("ul.homepageTabs li").eq(5).css("display", "inline-block");
$("ul.homepageTabs li").eq(5).addClass('animated fadeInDown');
}, 3300);
setTimeout(function () {
$("ul.homepageTabs li").eq(6).css("display", "inline-block");
$("ul.homepageTabs li").eq(6).addClass('animated fadeInDown');
}, 3600);
setTimeout(function () {
$("ul.homepageTabs li").eq(7).css("display", "inline-block");
$("ul.homepageTabs li").eq(7).addClass('animated fadeInDown');
}, 3900);
setTimeout(function () {
$("ul.homepageTabs li").eq(8).css("display", "inline-block");
$("ul.homepageTabs li").eq(8).addClass('animated fadeInDown');
}, 4200);
}
2 Answers 2
One simple solution would be to extract your common functionality into a method. We'll also cache the selector for speed (don't do this if the elements change).
var tabs = $("ul.homepageTabs li");
function animateAfter(index,timeout){
setTimeout(function () {
tabs.eq(index).css("display", "inline-block");
tabs.eq(index).addClass('animated fadeInDown');
}, timeout);
}
Then we can call it like so:
for(var i=3;i<8;i++){
animateAfter(i,2400+300*i);
}
I noticed the first two are intervals, was that a mistake? If it was, you can start the loop at 0 (and a smaller timeout). If it wasn't you can can create a similar function for intervals.
Also, consider using queued animations.
We want all our animations to occur 300 mili-seconds (after each other) right?
(function(){
var i=3; //the start index
function myAnimEffect(next){
$(this).eq(i).css("display", "inline-block").
eq(i).addClass('animated fadeInDown');
next();
}
var $el = $('ul.homepageTabs li');
$el.delay(1800);
for(var j=0;j<5;j++){ //5 is the number of lis
$el.queue(myAnimEffect).delay(300);
}
});
-
\$\begingroup\$ Why not chain .addClass to avoid re-querying? \$\endgroup\$papirtiger– papirtiger2013年11月12日 01:06:33 +00:00Commented Nov 12, 2013 at 1:06
If I am getting you right, you are looking for something like:
var titles=$("ul").children();
function fadeInTitles(titles, timeOut){
var timeOut=timeOut || 1500;
var len=titles.length, currentItem=0;
function showTitle(){
$(titles[currentItem]).fadeIn("slow");
currentItem+=1;
if(currentItem<len) setTimeout(showTitle, timeOut);
}
showTitle();
}
fadeInTitles(titles);
Play with me on jsFiddle.