How to disable click event in slideshow until animation is finished and then bind it again?

890 views Asked by At

I'm working on a slideshow, but I don't understand how I can unbind and rebind my buttons. What I wanted to happen is set it up, so that when the animation was triggered, the user couldn't click the button until the animation had completed.

This is the HTML Slider with prev and next buttons:

<div id="slider-container">

    <img id="slider-background" src=" ">

    <a class="prev"> </a>
    <a class="next"> </a>

    <div class="slider">
        <img class="slide" src=" ">
    </div>

    <div class="slider">
        <img class="slide" src=" ">
    </div>

    <div class="slider">
        <img class="slide" src=" ">
    </div>

    <div class="slider">
        <img class="slide" src=" ">
    </div>

    </div>
</div>

JQuery:

First img(0) that will be animated:

$(document).ready(function() {
    $('.slider > img').eq(0)
    .animate({top:"-=460px"},900)
    .animate({top:"+=18px"},300)
    .animate({top:"-=8px"},300)
    startSlider();  
});

This is the interval function that loads the next images and animate them:

function startSlider() {

    sliderInt=0;
    sliderNext=1;
    count = $('.slider img').size();

    loop = setInterval(function(){

    if(sliderNext >= count) {
        sliderNext=0;
        sliderInt=0;
    }

    $('.slider img').eq(sliderNext-1).animate({top:"-=25px"},400)
    .animate({top:"+=475px"},900);

    $('.slider > img').eq(sliderNext)
    .delay(1000)
    .animate({top:"-=460px"},900)
    .animate({top:"+=18px"},300)
    .animate({top:"-=8px"},300);

    sliderInt = sliderNext;
    sliderNext = sliderNext+1;

    },6000)

}

Bind next button to function:

$('.next').bind('click', next);

function next() {
    newSlideNext = sliderInt+1;
    showSlideNext(newSlideNext);
}

Bind prev button to function:

$('.prev').bind('click', prev);

function prev() {
    newSlidePrev = sliderInt-1;
    showSlidePrev(newSlidePrev);

}

shows the next image:

function showSlideNext(idNext) {

    stopLoop();

    if(idNext >= count) {
        idNext=0;
    }

    $('.slider img').eq(idNext-1).animate({top:"-=25px"},400)
    .animate({top:"+=475px"},900);

    $('.slider > img').eq(idNext)
    .delay(1000)
    .animate({top:"-=460px"},900)
    .animate({top:"+=18px"},300)
    .animate({top:"-=8px"},300);  

    sliderInt = idNext;
    sliderNext = idNext+1;

    startSlider();

}

shows the previous image:

function showSlidePrev(idPrev) {

    stopLoop();

    $('.slider img').eq(idPrev+1).animate({top:"-=25px"},400)
    .animate({top:"+=475px"},900);

    $('.slider > img').eq(idPrev)
    .delay(1000)
    .animate({top:"-=460px"},900)
    .animate({top:"+=18px"},300)
    .animate({top:"-=8px"},300);

    sliderInt = idPrev;
    sliderNext = idPrev+1;

    startSlider();

}
2

There are 2 answers

1
Mister Epic On BEST ANSWER

This is shooting from the hip here, so I apologize for any typos (just about to board a plane).

Don't bother with binding and unbinding your event handlers, just create a boolean flag which will indicate if you are in the middle of an animation:

 var isAnimating = false;

Then add this to your event handlers:

function next() {
   if(!isAnimating){
       isAnimating = true;
       newSlideNext = sliderInt+1;
       showSlideNext(newSlideNext);
  }
}

This will prevent next() from kicking off another animation, do the same for prev()

Now, you need some way to indicate the animation has completed. The best place to do that is probably in an animate() callback:

 .animate({property:"value"},duration, function(){ isAnimating = false };)

ref: http://api.jquery.com/animate/ (see the "complete" callback)

0
Mathieu Labrie Parent On

You can easilly make this with a flag.

var animationRunning = false;

function showSlideNext(idNext) {
    if (!animationRunning) {
        animationRunning = true;
        //do what ever
        //animation done
        animationRunning = false;
    }

}

This wait the click or next or prev will have no effect. I'm sure you get the idea.