回调CSS动画结束

时间:2015-11-27 00:33:16

标签: javascript jquery css css3 promise

我有一个小的jQuery函数,其中必须在子函数中触发返回值。原因:我想稍后使用其他jQuery函数链接此函数。但是下一个链接函数应该在main函数返回jQuery对象

之后启动
app.h.aniend = 'webkitAnimationEnd oanimationend msAnimationEnd animationend';
$.fn.animate_scale = function( callback ) {
    var $this = $(this);
    $this.addClass('animate_scale').one( app.h.aniend, function() {
        $(this).removeClass('animate_scale');
        if( typeof callback === 'function' ) {
            callback($this);
        }
        return $this; // return here...
    });
    // return $this;
};

是否可以说jQuery要等到子函数返回必要的jQuery对象进行链接?

$('#my_object').animate_scale().fadeOut(2000);

3 个答案:

答案 0 :(得分:5)

  

$( '#my_object')的 animate_scale ()的淡出(2000);

如果您希望.fadeOut()等待animate_scale()完成,animate_scale需要排队:

对您的插件进行排队:

通常,当您 fx methods时,例如:

$("#ball").animate({left:200}).fadeOut();

你会看到球的动画,只有动画完成后才会消失 - 它会淡出 为什么?因为jQuery会将animatefadeOut转移到queue数组中,并在触发下一个方法之前等待每个解析。

要在插件中复制相同的行为:

<强> jsFiddle demo (Queue in action!)

$.fn.animate_scale = function( callback ) {
    var $this = this;
    return $this.queue(function() { 
        $this.addClass('animate_scale').on("animationend", function() {
            $this.dequeue();
            if (typeof callback == 'function') callback.call( $this );
        });
    });
};


$('#my_object').animate_scale(function() {
    console.log( "Scale is done!" );
}).fadeOut( 2000 ); // fadeOut will wait for animate_scale to dequeue (complete)

我不需要队列堆叠

如果您希望您的插件以无阻碍(同时)方式处理其他链式 fx 方法, 只使用回调:

<强> jsFiddle demo (no Queue)

$.fn.animate_scale = function( callback ) {
  var $this = $(this);
  return $this.addClass('animate_scale').on("animationend", function() {
      if (typeof callback == 'function') callback.call( this );
  });
};

$('#my_object').animate_scale(function(){
    console.log("Scale done.");
                  // use $(this).fadeOut(2000); here!! cause otherwise...
}).fadeOut(2000); // ...if chained here, will fade immediately!!!!!

答案 1 :(得分:1)

最简单的方法是使用回调:

$('#my_object').animate_scale(function(){ $(this).fadeOut(2000) });

有一种非常糟糕的方法可以让你完全按照自己的意愿行事,但同样非常糟糕:

app.h.aniend = 'webkitAnimationEnd oanimationend msAnimationEnd animationend';
$.fn.animate_scale = function( callback ) {
    var $this = $(this);
    var fadeoutTime;
    $this.addClass('animate_scale').one( app.h.aniend, function() {
        $(this).removeClass('animate_scale');
        if( typeof callback === 'function' ) {
            callback($this);
        }
        if(fadeoutTime) {
          $(this).fadeOut(fadeoutTime);
        }
    });
    return {
      fadeOut: function(time) { fadeoutTime = time; }
    };
};

我重申,这是OVERKILL,因为你可以使用回调,因为你只限于fadeOut,但是它的作用是存储fadeOut调用的值,直到你实际想要淡出,然后使用它。如果你永远不会FadeOut,那么fadeoutTime仍然是undefined,并且不会发生淡出。

答案 2 :(得分:1)

您可以考虑一种通用方法:

  • 不依赖于特定的CSS3选择器
  • 将模仿jQuery的内置动画,例如slideDown()fadeIn()

如果是这样,那么该方法(让我们称之为.css3Animate())应该在以下情况的所有下工作:

// method-chain
$('#my_object').css3Animate('animate_scale').fadeOut(1000);
// callback
$('#my_object').css3Animate('animate_scale', function() {
    $(this).fadeOut(1000);
});
// .promise().then()
$('#my_object').css3Animate('animate_scale').promise().then(function() {
    $(this).fadeOut(1000);
});

以下jQuery插件实现了这些目标...

(function($) {
    var aniend = 'webkitAnimationEnd oanimationend msAnimationEnd animationend';
    $.fn.css3Anim = function(cssClass, callback) {
        var $this = this; // As we're in a plugin, `this` is already a jQuery collection.
        return this.queue(function(next) { // put the css animation in the elements' fx queue.
            $this.queue(function(){}) // block the animation queue while the CSS transition is in progress.
            .one(aniend, function() {
                if(callback && typeof callback === 'function') {
                    callback.call(this);
                }
                $this.removeClass(cssClass) // ready for another invocation
                .dequeue(); // allow the fx animation queue to progress, and resolve the associated promise.
            })
            .addClass(cssClass); // stimulate the required animation
            next(); // progress to the queue blocker above.
        });
    };
})(jQuery);

http://jsfiddle.net/sy51tyn5/1/

行为好但不完美。该插件旨在允许两个或多个这些动画排队,但只取得部分成功。它似乎允许两个,但三个分开。

正如您将看到的,在演示中,当动画正在进行时,按钮被禁用。这可以防止&#34;干涉&#34;而CSS3动画正在进行中。尝试取消选中该复选框,然后点击按钮;你会发现它很容易引起不安。

可能这是因为next()无法保证进入队列拦截器 - 其他可能会干预?需要做更多的工作来解决这个问题。也许聪明的人可以提供建议吗?