I'm building a simple slideshow using jQuery. I have the basics down, but as a relative jQuery newcomer, I feel like I'm fighting with the animation queue and not making much progress.
I've created a slideshow by making a function that receives a numeric index of the first slide to show. It fades in the slide, pauses, fades out the slide, then calls itself, passing the nu开发者_运维百科meric index of the next slide. This much works perfectly.
The problem happens when I try to allow user interaction. I've created a button that should allow the user to start the slideshow at a specific slide. This button clears the queue, then fades out the current slide, then starts the slideshow function, passing in the index of a specific slide to start at. This also works well. Problems start to happen when the button is clicked quickly several times. Quirky things start happening, like the intended slide will fade in, but only halfway, or the slide following it fades in several times in a row.
I've tried throwing "stop()" and "clearQueue()" in at semi-random places, but so far I haven't much luck. For someone with a firm grasp on how the animation queue works, this is (hopefully) a simple fix -- unfortunately, that someone is not me yet.
Here's the heart of the code. To see a live, ultra-simplified version of the problem, see: http://martinsmucker.com/demo/slideshow.html
HTML:
<div id="slideshow_container">
<div class="slide" id="slide1"></div>
<div class="slide" id="slide2"></div>
<div class="slide" id="slide3"></div>
<div class="slide" id="slide4"></div>
</div>
<button>Purple</button>
jQuery:
runSlideShow(1);
$('button').click(function(){
$('.slide:visible').clearQueue().fadeOut(500, function(){
runSlideShow(3);
});
});
function runSlideShow (slideNumber)
{
$('#slide' + slideNumber).fadeIn(500).delay(3000).fadeOut(500, function() {
// if we're on the last slide (number 4), start over at number 1
if (slideNumber == 4) {
runSlideShow(1);
}
// otherwise, just move to the next slide
else {
slideNumber++;
runSlideShow(slideNumber);
}
});
}
Any help is much appreciated, thanks!
Instead of using .clearQueue()
use .stop(true,true)
(ref)
Here is an updated demo.
One way I've handled this in the past is to use a tracking variable to indicate when animation is executing (such as 'isAnimating'). In the click listener, I first check to see if isAnimating=true. If so, skip it. Otherwise, set isAnimating=true and execute the animation. Inside the callback for the animation, I reset isAnimating back to false.
Disable the button until the animation is complete then re-enable?
If this is going to be a larger project then it might be an idea to use a good scroller plugin (although it is great to make one for yourself).
Have a look at JQuery Scrollable i have just implemented on this page tonight (wait a couple of sec for the top are to load, or check out the bottom right history section with the arrows.
Top Scroller Code
$('.section_2').scrollable({circular: true, mousewheel: true, speed: 1000}).autoscroll({
interval: 5000
});
var api = $(".section_2").data("scrollable");
// do something upon scroll
api.onSeek(function() {
//console.info("current position is: " + this.getIndex())
});
Bottom Scroller Code
$('.timeline-container').scrollable({circular: true, next: ".timeline-next", prev: ".timeline-prev"});
var api_timeline = $(".timeline-container").data("scrollable");
//console.info(api_timeline.getSize());
var timeline_random_index = Math.floor( Math.random() * ( api_timeline.getSize()+1) )+1;
//console.info(timeline_random_index);
api_timeline.seekTo( timeline_random_index, 0 );
精彩评论