What is the true way of adding callback functionality to custom JQuery Animation?

流过昼夜 提交于 2019-12-25 03:59:14

问题


i've found a shake effect in stackoverflow question (here)
Code is like below;

jQuery.fn.shake = function(intShakes, intDistance, intDuration) {
    this.each(function() {
        $(this).css("position","relative"); 
        for (var x=1; x<=intShakes; x++) {
        $(this).animate({left:(intDistance*-1)}, (((intDuration/intShakes)/4)))
    .animate({left:intDistance}, ((intDuration/intShakes)/2))
    .animate({left:0}, (((intDuration/intShakes)/4)));
    }
  });
return this;
};

but i need a way to add a callback function (or any other simple way) for chaging border color of shaking element before the effect and toggle to orginal color after animation complate.
I tried like below but no chance (border is turning original color immediately)

jQuery.fn.shake = function(intShakes, intDistance, intDuration,callback) {
    this.each(function() {
        $(this).css("position","relative"); 
        for (var x=1; x<=intShakes; x++) {
        $(this).animate({left:(intDistance*-1)}, (((intDuration/intShakes)/4)))
    .animate({left:intDistance}, ((intDuration/intShakes)/2))
    .animate({left:0}, (((intDuration/intShakes)/4)));
    }
  });
if(callback) callback();
return this;
};

and call like this

$elem.css('borderColor','red');
$elem.shake(3,5,500,function(){
$elem.css('borderColor','#a6caf0');})

You can find a JSFiddle Example here.(If you cancel callback function in fiddle you'll see that borders become red correctly but callback fails.)
Thaks right now...


回答1:


Here you go:

$.fn.shake = function ( times, distance, duration, callback ) {
    return this.css({ position: 'relative' }).each( function () {            
        for ( var i = 0, t = duration / times; i < times; i+= 1 ) {
            $( this ).
                animate({ left: -distance }, t / 3 ).
                animate({ left:  distance }, t / 3 ).
                animate({ left:         0 }, t / 4 );
        }

        $( this ).show( callback );
    });
};

And then...

$( button ).click( function () {
    $( field ).addClass( 'shaking' ).shake( 5, 10, 500, function () {
        $( this ).removeClass( 'shaking' );
    });
});

Live demo: http://jsfiddle.net/f96ff/8/

A timer is not needed. You just add the callback function to the effects queue via the (neutral) .show() method. This ensures that the callback is invoked only after all the animations (from the queue) have finished.

Additionally, I recommend a CSS class for the "shaking" state:

.shaking { border-color: red; }

Also, notice that I significantly refactored the code for $.fn.shake. I recommend you to take a few minutes of your time to analyze how I improved the code.




回答2:


You have to set a timeout, you cant just call the callback directly because the animate function of jquery is async. So it will execute the callback directly. What can be done is set a timeout to the time of the total animation.

You also can't just use the callback of the animate function of jQuery because you are using multiple.

Solution: http://jsfiddle.net/f96ff/2/



来源:https://stackoverflow.com/questions/8101717/what-is-the-true-way-of-adding-callback-functionality-to-custom-jquery-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!