Question

Hi I have problem with my slider please visit this site and check http://paruyr.bl.ee/ after click on my arrows it becomes work in an asynchronous way, ones it changes very fast and then slow and it repeats. I think it is from start slider and stop slider.

        var sliderPrev = 0,
        sliderNext = 1;


$("#slider > img").fadeIn(1000); 
startSlider();

function startSlider(){

    count = $("#slider > img").size();
    loop = setInterval(function(){

        if (sliderNext>(count-1)) {
            sliderNext = 0;
            sliderPrev = 0;
        };

        $("#slider").animate({left:+(-sliderNext)*100+'%'},900);
        sliderPrev = sliderNext;
        sliderNext=sliderNext+1;

    },6000)
}

function prev () {
    var newSlide=sliderPrev-1;
    showSlide(newSlide);
}

function next () {
    var newSlide=sliderPrev+1;
    showSlide(sliderNext);
}

function stopLoop () {
    window.clearInterval(loop);
}

function showSlide(id) {
    stopLoop();
    if (id>(count-1)) {
            id = 0;
        } else if(id<0){
            id=count-1;
        }

        $("#slider").animate({left:+(-id)*100+'%'},900);
        sliderPrev = id;
        sliderNext=id+1;
        startSlider();

};

$("#slider, .arrows").hover(function() {
    stopLoop()
}, function() {
    startSlider()
});

function onlyNext () {
        var newSlide=sliderPrev+1;
        onlyShowSlide(newSlide);
}

function onlyShowSlide(id) {

    if (id>(count-1)) {
            id = 0;
        } else if(id<0){
            id=count-1;
        }

        $("#slider").animate({left:+(-id)*100+'%'},900);
        sliderPrev = id;
        sliderNext=id+1;        
};
Was it helpful?

Solution

I think the best option would be to check if the animation is in progress and prevent the action if it is, something like this:

function prev () {
    if(!$('#slider').is(":animated"))
    {
        var newSlide=sliderPrev-1;
        showSlide(newSlide);
    }
}

function next () {
    if(!$('#slider').is(":animated"))
    {
        var newSlide=sliderPrev+1;
        showSlide(sliderNext);
    }
}

To illustrate the difference between this and just sticking a stop() in, check this JSFiddle. You will notice some choppy movements if you click multiple times in the stop() version.

OTHER TIPS

What I would do is add a class to your slider when the animation starts and remove the class when it finishes:

$("#slider").animate({left:+(-id)*100+'%'}, {
    duration: 900,
    start: function() {
        $('#slider').addClass('blocked');
    },
    complete: function() {
        $('#slider').removeClass('blocked');
    }
});

Now check on each click event if the slider is blocked or not:

function next () {
    if (!$('#slider').hasClass('blocked')) {
        var newSlide=sliderPrev+1;
        showSlide(sliderNext);
    }
}

This is a very simple solution, I'm sure there is a better one.

EDIT: As marcjae pointed out, you could stop the animations from queuing. This means when you double click, the slideshow still will move 2 slides. With my approach the second click will be ignored completely.

You can use a variable flag to control if the animation is still being done, or simply use .stop() to avoid stacking the animation.

$("#pull").click(function(){
    $("#togle-menu").stop().slideToggle("slow");
});

It is occurring because your animations are being queued.

Try adding:

.stop( true, true )

Before each of your animation methods. i.e.

$("#slider").stop( true, true ).animate({left:+(-id)*100+'%'},900);

The answers about stop are good, but you have a bigger issue that is causing the described behavior. The issue is here:

$("#slider, .arrows").hover(function() {
    stopLoop()
}, function() {
    startSlider()
});

You have bound this to the .arrows as well as the #slider and the arrows are contained within the slider. So, when you mouse out of an arrow and then out of the entire slider, you are calling start twice in a row without calling stop between. You can see this if you hover onto the arrow and then off of the slider multiple times in a row. The slides will change many times after 6 seconds.

Similarly, consider the case of a single click:

Enter the `#slider` [stopLoop]
Enter the `.arrows` [stopLoop]
Click the arrow     [stopLoop]
                    [startSlider]
Leave the `.arrows` [startSlider]
Leave the `#slider` [startSlider]

As you can see from this sequence of events, startSlider is called 3 times in a row without calling stopLoop inbetween. The result is 3 intervals created, 2 of which will not be stopped the next time stopLoop is called.

You should just have this hover on the #slider and more importantly, add a call to stopLoop as the first step in startSlider. That will ensure that the interval is always cleared before creating a new one.

$("#slider").hover(function() {
    stopLoop()
}, function() {
    startSlider()
});

function startSlider(){
    stopLoop();

    /* start the slider */
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top