NEB
NEB

Reputation: 734

Jquery - Using promise API

I was trying to create a simple progress bar. I need to get an event / perform action when the animation on the progress bar complete (100% width is filled by green color).

HTML -

<button>Go</button>
<p>Waiting</p>
<div id="bar" class="progress-bar">
    <div class="progress-bar-fill"></div>
</div>

CSS -

.progress-bar {
    background-color: #EEE;
    height: 10px;
    overflow: hidden;
    width:100%;
}
.progress-bar-fill {
    background-color: green;
    height: 100%;
    transition: width 5s ease 0s;
    width: 0;
}

JS -

$("button").on("click", function () {
    $("p").append(" --> Started");
    $('#bar .progress-bar-fill').css('width', '100%');
    $('#bar .progress-bar-fill').promise().done(function () {
        $("p").append(" --> Finished");
    });
});

Link - http://jsfiddle.net/v2unc/

WRT the code, the "Finished" indication should come after 5 seconds. But its coming as soon as the button is clicked.

The example in "http://api.jquery.com/promise/" works perfectly. Or am I looking at the wrong API?

Upvotes: 0

Views: 204

Answers (2)

A. Wolff
A. Wolff

Reputation: 74420

Use ontransitionend event for CSS3 animation:

DEMO

$("button").on("click", function () {
    $("p").append(" --> Started");
    $('#bar .progress-bar-fill').css('width', '100%').on('transitionend', function () {
        $("p").append(" --> Finished");
    });
});

Upvotes: 3

Jon
Jon

Reputation: 437664

You are looking at the wrong API. .promise returns a promise that gets fulfilled when a queue of pending operations on an element has been completed. By default this means the animation queue. Your progress bar is not being animated by jQuery, so the animation queue is empty at all times and the promise resolves immediately.

Since the progress bar is being animated by a CSS transition, the simplest thing you can do is set a timer synchronized with the transition duration, e.g.

$("button").on("click", function () {
    $("p").append(" --> Started");
    $('#bar .progress-bar-fill').css('width', '100%');
    setTimeout(5000, function () {
        $("p").append(" --> Finished");
    });
});

Of course this is rather low tech and requires you to repeat the transition duration (bad). Instead of this, prefer the transitionEnd event.

Upvotes: 4

Related Questions