serg
serg

Reputation: 111265

Troubles with creating jQuery animation sequence

I am trying to execute an animation sequence on progress bars:

function animateProgress() {
    var params  = [{from: 50, to: 100}, {from: 0, to: 100}, {from: 0, to: 50}];
    animateProgressStep(params, 0);
}

function animateProgressStep(params, i) {
    $(".progress").width(params[i].from).animate({width: params[i].to}, {
        duration: 2000, 
        complete: function() {
            if(i + 1 < params.length) {
                animateProgressStep(params, i + 1);
            } 
        }
    });
}

This works if there is a single bar on the page, but if there are many, it breaks on the second iteration because complete callback is called as many times as there are progress bar elements on the page.

What would be a solution?

Can play with it here: http://jsfiddle.net/TythE/1/

Upvotes: 0

Views: 117

Answers (3)

serg
serg

Reputation: 111265

I ended up starting animation sequence for each element, I feel it is the cleanest and easiest solution:

function animateProgress() {
    var params  = [{from: 50, to: 100}, {from: 0, to: 100}, {from: 0, to: 50}];
    $(".progress-overlay").each(function(){
        animateProgressStep($(this), params, 0);
    });
}

function animateProgressStep(el, params, i) {
    el.width(params[i].from).animate({width: params[i].to}, {
        duration: 2000, 
        complete: function() {
            if(i + 1 < params.length) {
                animateProgressStep(el, params, i + 1);
            } 
        }
    });
}

Upvotes: 0

pimvdb
pimvdb

Reputation: 154818

If I don't misunderstand you, you can add a finished property to each param so that it always continues to the next one only once:

function animateProgress() {
    var params  = [{from: 50, to: 100}, {from: 0, to: 100}, {from: 0, to: 50}];
    animateProgressStep(params, 0);
}

function animateProgressStep(params, i) {
    $(".progress").width(params[i].from).animate({width: params[i].to}, {
        duration: 2000, 
        complete: function() {
            if(i + 1 < params.length && !params[i].finished) {
                params[i].finished = true;
                animateProgressStep(params, i + 1);
            } 
        }
    });
}

Upvotes: 1

FishBasketGordo
FishBasketGordo

Reputation: 23132

I hope I'm understanding you correctly:

The animate method is operating on all the elements that have the class progress. Instead of selecting only on the class, why don't you use an ID?

function animateProgressStep(id, params, i) {
    $("#" + id).width(params[i].from).animate({width: params[i].to}, {
        duration: 2000, 
        complete: function() {
            if(i + 1 < params.length) {
                animateProgressStep(id, params, i + 1);
            } 
        }
    });
}

Upvotes: 0

Related Questions