Reputation: 133
I created a function that iterates over a set of divs, looping, fading in and out the next one.
What I am trying to do is to stop it upon either 'click', if/else, or focus. In doing some searching, it seems that I can utilize the setTimeout
- clearTimeout
functions. However I am a bit unclear on how to go about it, and maybe implementing it incorrectly.
HTML:
<a href="#" class="killFunc">Kill Loop Function</a>
<div id="productBox">
<h3>Dynamic Title Here</h3>
<div class="divProduct">
<!-- product image -->
<div class="product-discription">
<h4>Product 1</h4>
<p>Cras justo odio, dapibus ac facilisis in.</p>
<a href="#">Learn More</a>
</div>
</div>
<!-- Repeat '.divProduct' over and over -->
</div>
JS:
timer = null;
function productTypeCycle(element) {
timer = setTimeout(function() {
element.fadeIn()
.delay(1000)
.fadeOut(function() {
if(element.next().length > 0) {
productTypeCycle(element.next());
}
else {
productTypeCycle(element.siblings(":nth-child(2)"));
}
});
}, 500);
}
$(document).ready(function() {
productTypeCycle($(".divProduct:first"));
$(".killFunc").click(function(e) {
e.preventDefault();
if(timer !== null) {
clearTimeout(timer);
}
});
});
Of course, as usual, I am probably way over thinking something that could be so simple.
Upvotes: 0
Views: 905
Reputation: 57204
the problem here is that you stop your timer correctly, but sadly your timer has internally via jQuery started another "timer" for the animations. you would need to stop the animation instead of the timer:
var animationEle = null;
function productTypeCycle(element) {
animationEle = element;
element.fadeIn()
.delay(1000)
.fadeOut(function () {
if (element.next().length > 0) {
productTypeCycle(element.next());
} else {
productTypeCycle(element.siblings(":nth-child(2)"));
}
});
}
$(document).ready(function () {
productTypeCycle($(".divProduct:first"));
$(".killFunc").click(function (e) {
e.preventDefault();
if (animationEle)
$(animationEle).stop(true, false);
});
});
Upvotes: 1
Reputation: 9224
Another (cleaner) way to go about it, is to let the last animation finish, but set a value to stop any further animations.
Like this.
timer = null;
var animationCancelled = false;
function productTypeCycle(element) {
timer = setTimeout(function() {
element.fadeIn()
.delay(1000)
.fadeOut(function() {
if(animationCancelled) return;
if(element.next().length > 0 ) {
productTypeCycle(element.next());
}
else {
productTypeCycle(element.siblings(":nth-child(2)"));
}
});
}, 500);
}
$(document).ready(function() {
productTypeCycle($(".divProduct:first"));
$(".killFunc").click(function(e) {
e.preventDefault();
if(timer !== null) {
clearTimeout(timer);
animationCancelled = true;
}
});
});
Upvotes: 1
Reputation: 9224
The issue is the fade, not the timer. The fade is still executing. You need to run $(element).stop(); on all the elements that have started an animation otherwise they'll just continue.
Upvotes: 0