在jquery插件中添加done()函数,等待动画结束

Fab*_*aio 2 jquery plugins promise deferred jquery-deferred

我的问题是当我添加一个:

.done(function() {
  innerDef.resolve();                    
});
Run Code Online (Sandbox Code Playgroud)

在"动画"功能中,它不能按我的意愿工作.
我只是希望函数等到动画结束,如下所示:

$('#anim_vision').showThis().done(function(){
   alert('task finished!');
});
Run Code Online (Sandbox Code Playgroud)

我的完整插件代码:

(function ($) {

    $.fn.extend({    
        showThis: function (options) {    
            var def = $.Deferred();

            var options = $.extend(options);
            var deferredList = [];

            this.each(function () { 
                var innerDef = $.Deferred();
                deferredList.push(innerDef.promise());

                $( this )
                .children('.texto')
                .removeClass('opacity_none')
                .css('display','block');

                $( this )
                .animate({'height':'100%'}, 900, 'easeOutQuad')
                .done(function() {
                    innerDef.resolve();                    
                });
                });

            $.when.apply($, deferredList).done(function() {
               def.resolve(); 
            });

            return def.promise();
        }
    });
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

我真的需要帮助!

jfr*_*d00 6

常规jQuery对象没有.done()方法.您需要.promise()通过更改以下内容来调用以获取动画的promise对象:

            .animate({'height':'100%'}, 900, 'easeOutQuad')
            .done(function() {
                innerDef.resolve();                    
            });
Run Code Online (Sandbox Code Playgroud)

对此:

            .animate({'height':'100%'}, 900, 'easeOutQuad')
            .promise()
            .done(function() {
                innerDef.resolve();                    
            });
Run Code Online (Sandbox Code Playgroud)

但是,你可以直接使用承诺来简化事情,而不是自己做innerDef.


进一步简化事情,你不需要自己推迟,因为你可以从$.when()以下方面返回承诺:

(function ($) {

    $.fn.extend({    
        showThis: function (options) {    
            var options = $.extend(options);
            var promiseList = [];

            this.each(function () { 

                $( this )
                    .children('.texto')
                    .removeClass('opacity_none')
                    .css('display','block');

                // run the animation,
                // get a promise object for the animation queue,
                // put it in our list of promises
                promiseList.push(
                     $( this )
                     .animate({'height':'100%'}, 900, 'easeOutQuad')
                     .promise()
                );
            });

            // return a new promise that is resolved 
            // when all the animations are done
            return $.when.apply($, promiseList);
        }
    });
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

经过进一步的研究,您可以更加简化这一点:

jQuery.fn.extend({    
    showThis: function () {    
        return (this
          .children('.texto')
          .removeClass('opacity_none')
          .css('display','block')
          .animate({'height':'100%'}, 900, 'easeOutQuad')
          .promise()
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

进一步变化:

  1. 您调用的所有jQuery方法都已遍历整个集合,因此您无需手动迭代它们this.each().
  2. 您没有使用options参数,因此您可以删除它.
  3. 您没有任何持久状态变量,因此您不需要围绕它的函数包装来隔离它们.
  4. .promise()当整个集合完成动画制作时,jQuery会解析,因此它可以帮助您.您不需要自己的$.when()或自己的promise数组.您可以返回.promise()之后的内容.animate(),它将在所有动画完成后解析.

你可以看到这个演示,看看如何.promise()等待整个集合动画制作:http://jsfiddle.net/jfriend00/Erq5Q/.