jquery - 在jquery插件中添加done()函数以等待动画完成

标签 jquery plugins promise jquery-deferred deferred

我的问题是当我添加:

.done(function() {
  innerDef.resolve();                    
});

在“动画”功能中,它没有按我想要的方式工作。
我只想让函数等待动画完成,如下所示:

$('#anim_vision').showThis().done(function(){
   alert('task finished!');
});

我的完整插件代码:

(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);

我真的需要帮助,拜托!

最佳答案

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

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

对此:

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

但是,您可以直接使用 Promise 来简化事情,而不用创建自己的 innerDef

<小时/>

进一步简化事情,您也不需要自己进行延迟,因为您只需从 $.when() 返回 promise 即可:

(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);
<小时/>

经过进一步研究,您可以将其进一步简化为:

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

进一步更改:

  1. 您调用的所有 jQuery 方法都已迭代整个集合,因此您无需使用 this.each() 手动迭代它们。
  2. 您没有使用 options 参数,因此您可以将其删除。
  3. 您没有任何持久状态变量,因此不需要围绕它的函数包装器来隔离它们。
  4. jQuery 的 .promise() 会在整个集合完成动画处理后进行解析,以便它为您完成这项工作。您不需要自己的 $.when() 或自己的 Promise 数组。您只需返回 .animate() 之后的 .promise() 即可,当所有动画完成时它将解析。

您可以观看此演示,了解 .promise() 如何等待整个集合完成动画处理:http://jsfiddle.net/jfriend00/Erq5Q/ .

关于jquery - 在jquery插件中添加done()函数以等待动画完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23349310/

相关文章:

javascript - 从一小时的最后一分钟到下一小时的第一分钟

jquery - 可点击链接上方的 Div

PHP/MySQL : Group items by month

ruby-on-rails - 构建插件或 gem ?

javascript - 在 promise 链中访问先前履行的 promise 结果

Javascript生成动态数字字符串

jquery - Accordion div 外的 Accordion 内容

c++ - 传递多种数据类型的最佳方式

javascript - 根据 promise 的结果抛出错误

javascript - 为什么 JavaScript Promises 有时既不使用 .catch 也不使用 .then?