Home > OS >  jQuery: get animate to repeat only after full completion
jQuery: get animate to repeat only after full completion

Time:01-29

EDIT: thanks to mplungian, I now know about debounce and particularly about throttle which seems a very good solution to my problem. But I don't know how to implement this with jQuery "animate" yet.

I have this script:

$(document).on('click','#right',function(){
    if($(this).hasClass('ready')){
        $(this).removeClass('ready');
        $('#slider').animate(
            {'margin-left': '-=200px'},
            { duration:1100,easing:'easeOutElastic',queue: false,complete:function()
                {
                    $('#right').addClass('ready');
                }
            }
        )
        // ...
        sliderPosition  ;   
    }

})

So, this is a slider triggered on a button click. As there is a vital animation that has to be completed before the user clicks again (otherwise the slider width is quickly messed up), I used a "ready" class that prevents the user from clicking until the previous animation is finished.

Tehnically, it works well but it doesn't "feel" right, the slider doesn't look like "responsive" enough, as fast clickers will only get to see the slider move every other of their clicks.

But if I get rid of the ".ready" condition, then the slider is quickly messed up because each animation can be fired before the previous one is finished.

So, is there a way for the script to take each and every click into account but just differ them until all the previous iterations of the same animation are finished?

Thanks.

CodePudding user response:

Try adding .stop

$('#slider').stop().animate(

like this

$(document).on('click','#right',function(){
    if($(this).hasClass('ready')){
        $(this).removeClass('ready');
        $('#slider').stop().animate(
            {'margin-left': '-=200px'},
            { duration:1100,easing:'easeOutElastic',queue: false,complete:function()
                {
                    $('#right').addClass('ready');
                }
            }
        )
        // ...
        sliderPosition  ;   
    }
})

CodePudding user response:

It's been solved using throttle:

let timeout;

const throttle = (func, limit) => {
    if (!timeout) {
        func();
        timeout = setTimeout(function() {
          timeout = undefined;
        }, limit);
    }
};

$(document).on('click','#right',function(){
    throttle(function(){
        $('#slider').animate(
            {'margin-left': '-=200px'},
            { duration:1100,easing:'easeOutElastic',queue: false}
        )
        // ...
        sliderPosition  ; 
    }, 500);
})

It's the best of both worlds as the animations are served in a steady pace during the clicking no matter how many clicks. So this will give the impression that the slider is totally reactive while not necessarily firing an animation on each and every click if they are too quick and to numerous. So it's not so much about the amount of clicks than about keeping the animation going WHILE you are clicking.

  • Related