Reputation: 1978
I'm trying to pass an index of element and slideUp each list item content with delay
here is my code
for(var i = 1; i <= $("#colContainer li").length ; i++) {
var el = $("#colContainer li:nth-child(" + i + ") .colContent");
var delay = function() {
slide(el);
};
setTimeout(delay, 10);
function slide(el){
el.slideUp();
};
};
but every time just the last one slides up
what I expect is they slideUp from index 1 to the end with delay
I also tried this
index = $(this).parent("li").index();
for(var i = 1; i <= $("#colContainer li").length ; i++) {
(function(i) {
var el = $("#colContainer li:nth-child(" + i + ") .colContent");
var delay = function() {
slide(el);
};
setTimeout(delay, 10);
function slide(el){
el.slideUp();
};
})(i);
};
but they all slide at once, i want index 1 slide, after that index 2 and ...
IS THERE ANY WAY WITH FOR LOOP ??
Upvotes: 0
Views: 299
Reputation: 1172
Did you want them to be queued or for a 10 millisecond delay before they all slide up?
Do you require the for
loop?
Wouldn't the following do the latter?
setTimeout(function() {
$("#colContainer li .colContent").slideUp();
}, 10);
Queued slide example:
(function slideContent(index) {
$("#colContainer li:nth-child(" + index + ") .colContent").slideUp();
if ($("#colContainer li:nth-child(" + (index + 1) + ") .colContent").length == 1) {
setTimeout(function() { slideContent(index + 1); }, 250);
}
})(1);
Upvotes: 2
Reputation: 28349
Unless your intention is to have them all animate at the same time, you can't set them up in a loop this way. If you do, they're all executed (almost) simultaneously and as you say, you'll only actually see the last one.
You need to trigger each successive one from the completion of the previous one. Chain them together with callbacks.
delay
should set up the next setTimeout. Then you'll get the result you're after.
EDIT Given the other answers here, I'll add that you'll probably want to increase your pause time from 10ms to something like 100 and then use the *i solution that the others have suggested. Multiplying 10ms by i isn't going to get you a whole lot in the way of noticeable delay. I'd start with 100ms and if that's too jerky move down from there in increments of 10ms till you have an animation that makes you happy.
Upvotes: 0
Reputation: 189
You need a closure to scope the value of el for each iteration of the loop.
for(var i = 1; i <= $("#colContainer li").length ; i++) {
var el = $("#colContainer li:nth-child(" + i + ") .colContent");
(function(el) {
setTimeout(function(){
el.slideUp();
},10);
})(el);
}
However this will still cause them to all animate at the same time which if that is the desired result, you could just do it all in one step with jQuery. If you want them to animate one at a time you can do this:
for(var i = 1; i <= $("#colContainer li").length ; i++) {
(function(i) {
var el = $("#colContainer li:nth-child(" + i + ") .colContent");
setTimeout(function(){
el.slideUp();
}, i * 10);
})(i);
}
Upvotes: 6
Reputation: 324620
This is because var el
is scoped to the function block, not the loop block.
Try something like this:
for( var i=1; ......) { (function(i) {
var el = ...
// rest of your code, unchanged
})(i); }
Upvotes: 7