jQuery 1.6 introduced deferred.pipe() to provide a easier way for chained actions, and the $.animate() started supporting “deferred” as well. 

When I wanted to play jQuery animation effects of elements one by one, it often needed complex logic to accomplish the result, using complete callback with queue or setTimout timer trick, which are either lousy or complex.  I believe that deferred.pipe() can solve the problem more gracefully, so I tried.

I can’t find a exactly deferred.pipe() example for animation, the closest one is from github(https://gist.github.com/1026351), but it didn’t work in my test.   According to my understanding, the doneFilter should return observable object and $.animate() is a good choice, so I changed .pipe(function() { $(…).fadeIn() }) to .pipe(function() { return $(…).fadeIn(); }).  After the little modification, it works like a charm.

The sample code from github uses hard-code to assign animations, but using loop to append animations is more practical in my real cases.  By using jQuery.each() + deferred = deferred.pipe() trick, now I can use a loop to push animation actions into the pipeline successfully, too.

Here is my sample code, or you can see the live demo on JSFIDDLE(http://jsfiddle.net/KgY33/) as well.

<!DOCTYPE html>
 
<html>
<head>
    <title>Deferred.pipe() for Animation</title>
    <style type="text/css">
        #c1 { height: 80px; }
        #c1 div 
        { 
            display: none; width: 200px; height: 20px; text-align: center;
            margin: 5px; background-color: #dddddd; color: blue;
        }
        #container div  
        {
            width: 300px; padding: 5px; text-align: center; display: none;
            margin: 5px; border: 1px solid gray; background-color: #80ddf0;
        }
    </style>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js" 
     type="text/javascript"> </script>   
    <script type="text/javascript">
        $(function () {
 
            //Ref: https://gist.github.com/1026351
            $.Deferred(function (dfr) {
                dfr
                .pipe(function () { return $('.first').fadeIn(); })
                .pipe(function () { return $('.second').fadeIn(); })
                .pipe(function () { return $('.third').fadeIn(); })
            }).resolve();
 
            //Using Loop
            $.Deferred(function (dfr) {
                $("#container > div").each(function () {
                    var $div = $(this);
                    dfr = dfr.pipe(function () { return $div.fadeIn(); });
                });
            }).resolve();
        });
    </script>
</head>
<body>
<div id='c1'>
    <div class="first">First</div>
    <div class="second">Second</div>
    <div class="third">Third</div>
</div>
<div id='container'>
    <div>First</div>
    <div>Second</div>
    <div>Third</div>
    <div>Forth</div>
    <div>Fifth</div>
</div>
</body>
</html>

【中文摘要】剛好討論到用jQuery循序播放動畫的需求,想起jQuery 1.6新提供了deferred.pipe() API來,加上$.animate()在1.6也支援deferred,理論上應該可以寫得很漂亮才對,可惜網路上沒能找到直接的範例。我參考了一個github上的範例,修改讓它可以運作,並嘗試改寫出迴圈指定版,供大家參考。想直接看Demo的人可以看這裡


Comments

Be the first to post a comment

Post a comment