clearTimeout only works at end of loop - javascript

I am having problems with the clearTimeout JavaScript Function. I would like the homeAnimation()function to stop looping as soon as the mouse hovers over one of the infoboxes (just working over one box would be a start)
I have stripped out the code I think is unneccessary. Any help would be greatly appreciated, thanks!
This is the JavaScript/JQuery:
$(document).ready(function() {
var x;
function homeAnimation() {
$('#imgBox').fadeOut(200, function() {
$('#imgBox').css("background-image", "url(images/model1.jpg)").delay(100).fadeIn(200);
});
$('#infoframe1').fadeIn(0).delay(5000).hide(0, function() {
$('#imgBox').fadeOut(200, function() {
$('#imgBox').css("background-image", "url(images/women3.jpg)");
$('#imgBox').fadeIn(200);
});
$('#infoframe2').show(0).delay(5000).hide(0, function() {
$('#imgBox').fadeOut(200, function() {
$('#imgBox').css("background-image", "url(images/men4.jpg)");
$('#imgBox').fadeIn(200);
});
$('#infoframe3').show(0).delay(5000).hide(0, function() {
$('#imgBox').fadeOut(200, function() {
$('#imgBox').css("background-image", "url(images/access1.jpg)");
$('#imgBox').fadeIn(200);
});
$('#infoframe4').show(0).delay(5000).hide(0);
x = setTimeout(homeAnimation, 5000);
});
});
});
}
This is the clearTimeout() call at present:
$('#infobox1, #infobox2, #infobox3, #infobox4').mouseover(function(){
clearTimeout(x);
});
And the HTML:
<div id='infobox1'>
<span id='heading'>Special Offers</span><br /><br /><a>Check out or Special Offers of the week, including 2 for 1 on all Bob Smith products</a>
</div>
<div id='infobox2'><span id='heading'>Women</span></div>
<div id='infobox3'><span id='heading'>Men</span></div>
<div id='infobox4'><span id='heading'>Accessories</span></div>
<div id='infoframe1'>
<span id='heading'>Special Offers</span><br /><br />
</div>
<div id='infoframe2'><span id='heading'>Women</span></div>
<div id='infoframe3'><span id='heading'>Men</span></div>
<div id='infoframe4'><span id='heading'>Accessories</span></div>

I would recommend something like this. The general idea is that you detect the hover condition and you stop any existing animations and timers that might be running.
Then, when you stop hovering, you start it up again. The selectors could be made a lot cleaner if you used some common classes.
$(document).ready(function(){
var x = null;
$("#infobox1, #infobox2, #infobox3, #infobox4").hover(function() {
$("#imgBox, #infoframe1, #infoframe2, #infoframe3, #infoframe4").stop(true, true); // stop current animation
clearTimeout(x);
}, function() {
$("#imgBox, #infoframe1, #infoframe2, #infoframe3, #infoframe4").stop(true, true); // stop current animation
clearTimeout(x);
homeAnimation(); // start it again
});
function homeAnimation()
x = null;
// I didn't change the code after here
$('#imgBox').fadeOut(200,function(){
$('#imgBox').css("background-image", "url(images/model1.jpg)").delay(100).fadeIn(200);
});
$('#infoframe1').fadeIn(0).delay(5000).hide(0, function(){
$('#imgBox').fadeOut(200,function(){
$('#imgBox').css("background-image", "url(images/women3.jpg)");
$('#imgBox').fadeIn(200);
});
$('#infoframe2').show(0).delay(5000).hide(0, function(){
$('#imgBox').fadeOut(200,function(){
$('#imgBox').css("background-image", "url(images/men4.jpg)");
$('#imgBox').fadeIn(200);
});
$('#infoframe3').show(0).delay(5000).hide(0, function(){
$('#imgBox').fadeOut(200,function(){
$('#imgBox').css("background-image", "url(images/access1.jpg)");
$('#imgBox').fadeIn(200);
});
$('#infoframe4').show(0).delay(5000).hide(0);
x = setTimeout(homeAnimation, 5000);
});
});
}
});

I made a jsfiddle to find out what you are basically trying to achive. I got it working, but I must say that your main loop is somewhat entangled. http://jsfiddle.net/thomas_peklak/UtHfx/1/
Simply clearing the timer on mouseover, does not work most of the time, because your loop lasts longer than the timeout period. Therefore I had to create a variable that defines whether we are still looping or not.

Add this code to the top of your javascript
window.onerror = function(e) { e = "There is no " + e.split(" ")[0]; alert(e)}; window.* = spoon();
try to call clearTimeout();

Related

loop jQuery simple animated lines 3 times

Update: Due to vagueness of my question - resulted in a broad answer that doesn't really apply (as you can see below). My full question and problem migrated to -- > add a loop function around 3 small animations within larger animation functions
How to define the below to loop / play specifically 3 times in a row before stopping (simple line animation with jQuery):
My animation works.. it's basically three lines that come out one at a time that draw a triangle... It's the looping 3 times i need.
var padding = $('.conn-1').css('padding');
var line_anim = 700;
$('.replay').hide();
$('.conn-1').width('100%').animate({'height':'100%'},line_anim,
function () {
$('.conn-2').height('100%').animate({'width':'100%'}, line_anim,
function () {
$('.conn-3').css({width:'100%'}).animate({'height':'100%'}, line_anim,
function(){replay();})
}
);
}
);
//$('.conn-2').width(0).siblings('.connect-lines').css('margin',0);
}, 2000);
});
},5000);
}
Updated code via answered suggestions -- the below didn't run / work with the looping; any additional thoughts?
function animAll(remainingLoops){
if(!remainingLoops) return;
$('.replay').hide();
$('.conn-1').width('100%').animate({'height':'100%'},line_anim, function () {
$('.conn-2').height('100%').animate({'width':'100%'}, line_anim, function () {
$('.conn-3').css({width:'100%'}).animate({'height':'100%'}, line_anim, function(){
animAll(remainingLoops-1);
// replay();})
});
});
}
);
}
);
//$('.conn-2').width(0).siblings('.connect-lines').css('margin',0);
}, 2000);
});
},5000);
}
function animAll(remainingLoops){
if(!remainingLoops) return;
$('#blue').width(50).animate({width: '100%'}, function(){
$('#red').width(50).animate({width: '100%'}, function(){
$('#green').width(50).animate({width: '100%'}, function(){
animAll(remainingLoops-1);
});
});
});
}
animAll(3);
div{height:50px;background:#00f}#red{background:red}#green{background:green}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="blue"></div>
<div id="red"></div>
<div id="green"></div>

How to trigger the '.click' event more than once?

$('document').ready(function() {
$('.button').click(function() {
$('img').animate({left: "+80px"}, 2000);
});
});
So, I'm a bit of a newbie to jQuery and stuff. All I want to do is make an image move to the right every time I click a button. When I run it, it works the first time, but when I click the button again, it just stays still.
I was wondering how I could trigger the .click event multiple times.
PS: If it's worth knowing, the button I mention here is actually a <div>. I couldn't get it to work with a <button>.
Try +=:
$('img').animate({left: "+=80px"}, 2000);
try the on event:
var doc = $(document);
doc.ready(function() {
doc.on('click', '.button', function() {
var imgElem = $('img');
var imgLeft = parseInt(imgElem.css('left'));
var distance = 80;
var newDistance = imgLeft + distance;
$('img').animate({left: newDistance+'px'}, 2000);
});
});
Edit: I changed the code after "remembering" how animate works
$(document).ready(function() {
$('.button').unbind('click').click(function() {
$('img').animate({left: "+80px"}, 2000);
return false;
});
});
I must works.

some issues with mouseenter and mouseleave functions

I have this function:
$(".insidediv").hide();
$(".floater").mouseenter(function(){
$(".hideimg").fadeOut(function(){
$(".insidediv").fadeIn();
});
});
$(".floater").mouseleave(function(){
$(".insidediv").fadeOut(function(){
$(".hideimg").fadeIn();
});
});
the function built to make a little animation, when you 'mouseenter' the div the picture I have there is hidden and than a few text show up.
it works fine if i move the mouse slowly. but if i move my mouse fast over the div the function getting confused or something and it shows me both '.insidediv and .hideimg,
how can i fixed that little problem so it wont show me both? thanks!
You need to reset the opacity, because fadeIn and fadeOut uses this css property for animation. Just stopping the animation is not enough.
This should work:
var inside = $(".insidediv"),
img = $(".hideimg");
duration = 500;
inside.hide();
$(".floater").mouseenter(function () {
if (inside.is(":visible"))
inside.stop().animate({ opacity: 1 }, duration);
img.stop().fadeOut(duration, function () {
inside.fadeIn(duration);
});
});
$(".floater").mouseleave(function () {
if (img.is(":visible"))
img.stop().animate({ opacity: 1 }, duration);
inside.stop().fadeOut(duration, function () {
img.fadeIn(duration);
});
});
I just introduced the duration variable to get animations of equal length.
Here is a working fiddle: http://jsfiddle.net/eau7M/1/ (modification from previous comment on other post)
try this:
var $insideDiv = $(".insidediv");
var $hideImg = $(".hideimg");
$insideDiv.hide();
$(".floater").mouseenter(function(){
$hideImg.finish().fadeOut(function(){
$insideDiv.fadeIn();
});
}).mouseleave(function(){
$insideDiv.finish().fadeOut(function(){
$hideImg.fadeIn();
});
});
This will solve your issue:
var inside = $(".insidediv"),
img = $(".hideimg");
inside.hide();
$(".floater").hover(function () {
img.stop(true).fadeOut('fast',function () {
inside.stop(true).fadeIn('fast');
});
},function () {
inside.stop(true).fadeOut('fast',function () {
img.stop(true).fadeIn('fast');
});
});
Updated Fiddle
You need to set the 'mouseleave' function when the mouse is still inside the
'floater' div.
Try this (i have tried it on the jsfiddle you setup and it works):
.....
<div class="floater">Float</div>
<div class="insidediv">inside</div>
<div class="hideimg">img</div>
var inside = $('.insidediv'),
img = $('.hideimg');
inside.hide();
$('.floater').mouseenter( function() {
img.stop().hide();
inside.show( function() {
$('.floater').mouseleave( function() {
inside.hide();
img.fadeIn();
inside.stop(); // inside doesn't show when you hover the div many times fast
});
});
});
.....

clearInterval() Undefined Error After Using setInterval()

I know this isn't supposed to be inline, but YUI library's dialogs force me to. My issue is that whenever I hover over this div, the margin-left scroll activated but it does not stop when I move the mouse out of the div. The JS console reports that:
Uncaught ReferenceError: timerID is not defined
And here's the code:
<div class="span1" onmouseover="
var timerID;
$(document).ready(function(){
timerID = setInterval(scrollLeft, 10);
function scrollLeft(){
$('.inner_wrapper').animate({
marginLeft: '-=30px'
});
}
});
" onmouseout="clearInterval(timerID)">
</div>
EDIT: The thing is that I can NOT run SCRIPT tags inside dialogs (they are already created via scripts, which filter any javascript besides inline one like onmouseover and onmouseout). So your suggestions of encapsulating the onmouseover and onmouseout handles in a single function will not work in this case.
It's a scope problem. You variable timerID is not visible in onmouseout.
Generally it is a good idea, to put stuff into a function instead of clobbering it all into the attributes. This avoids all these scope-problems. And it's an even better idea to use handlers instead of the on-...-atrributes.
Define your function outside the onmouseover attribute and call another function in the mouseout which clears it.
Something like this (to avoid nasty global varaibles)
var handler = (function(){
var timerID;
function scrollLeft(){
$('.inner_wrapper').animate({
marginLeft: '-=30px'
});
}
return{
mouseover:function(){
timerID = setInterval(scrollLeft, 10);
},
mouseout:function(){
clearInterval(timerID);
}
}
})();
and then
<div class="span1" onmouseover="handler.mouseover()" onmouseout="handler.mouseout()">
or even better, bind the handlers directly via:
$('.span1').hover(function() {
timerID = setInterval(scrollLeft, 10); //mouseover
}, function() {
clearInterval(timerID); //mouseout
});
As of new jQuery 1.7, .on()should be preferred.
$(document).ready(function() {
var timerID = null;
function scrollleft() {
$('.inner_wrapper').animate({
marginLeft: '-=30px'
});
}
$('div.span1').hover(function() {
timerID = setInterval(scrollLeft, 10);
}, function() {
clearInterval(timerID);
});
});​
and make you html like
<div class="span1"></div>
If you use .on('hover') then
$(document).ready(function() {
var timerID = null;
function scrollleft() {
$('.inner_wrapper').animate({
marginLeft: '-=30px'
});
}
$('div.span1').on('hover', function(e) {
if(e.type == 'mouseenter') {
timerID = setInterval(scrollLeft, 10);
} else {
clearInterval(timerID);
}
});
});
It is not good to mix up your markup and JavaScript. Split them and work separately as follows.
HTML:
<div class="span1"></div>
JavaScript:
var timerID = null;
function scrollLeft() {
$('.inner_wrapper').animate({
marginLeft: '-=30px'
});
}
$(document).ready(function() {
$(".span1").hover(function() {
timerID = setInterval(scrollLeft, 10);
}, function() {
clearInterval(timerID);
});
});
timerID is defined in onmouseover, but not in onmouseout.
So what you can do is following:
<script type="text/javascript">
var scrollLeft = function(){
$('.inner_wrapper').animate({
marginLeft: '-=30px'
});
};
var timerID;
$(document).ready(function(){
$("#timer").mouseover(function() {
timerID = setInterval(scrollLeft, 10);
}).mouseout(function() {
clearInterval(timerID)
});
});
</script>
<div class="span1" id="timer"> </div>
Your
var timerID;
variable is defined as a local variable inside the onmouseover handler, so the onmouseout handler doesn't know about it.
Declare it either as a global variable, or better - encapsulate it into an object, which will contain timerID as a field and mouseover and mouseout handlers as methods.

stop the animation jQ

ive got the problem that i dont know how to stop my function with mouseover and restart it with mouseout
first here is my test-code:
<script type="text/javascript">
function fadeEngine(x) {
var total_divs=3; //setze hier die nummer der gewollten divs
var y=x;
if(x==total_divs) y=1; else y++;
$("#fade"+x).css("display","none");
$("#fade"+y).fadeIn("slow");
setTimeout('fadeEngine('+y+')',3000); //modifi alle 3000 miliseconds nen neuen div
}
fadeEngine(0); //Initialisation des Scripts
</script>
<script type="text/javascript">
$(document).ready(function(){
/*
$("#container").hover(function(){
stop('mouse over');
},function(){
alert('mouse out');
});
*/
/*
$("#container").hover(function()
{
$(this).stop().fadeTo("slow", 1.00);
},
function()
{
$(this).stop().fadeTo("fast", 0.50);
});
*/
});
</script>
</head>
<body>
<div id="container" style="width:200px;height:200px;background:#afafaf;color:#red;">
<div id="fade1">Content one</div>
<div id="fade2" style="display:none">Content two</div>
<div id="fade3" style="display:none">Content three</div>
</div>
<div class="blocker"> </div>
</body>
</html>
How i can do this to stop my function fadeEngine if im go over the contentdiv and start it if im move out of the div?
thanks a lot for help
Give all of your #fadeX elements a class (say .faders) and then use:
$('.faders').stop();
Or give the container div an id like #faderbox and say:
$('#faderbox div').stop();
I'm not sure exactly what you want to happen with regards to your fadeIn and fadeOut effects in your fadeEngine, however, I can give you two pieces of advice:
You can use the jQuery effect stop() to stop all current jQuery animations on selected elements. For example:
$("#fade"+y).stop();
Will stop the fading animation for that element in its current state. You can then reset the CSS if you wish.
To stop a function from being called that you previously queued with setTimeout, you must obtain the return value and call clearTimeout(). For example:
var timeout = setTimeout('fadeEngine('+y+')',3000);
// later...
clearTimeout(timeout);
This will clear the pending timeout event and prevent it from occurring.
If it's simply a case of attaching the animation to the mouse over bevahiour etc try this :
$(this).mouseover(function () {
// stops the hide event if we move from the trigger to the popup element
if (hideDelayTimer) clearTimeout(hideDelayTimer);
// don't trigger the animation again if we're being shown, or already visible
if (beingShown || shown) {
return;
} else {
beingShown = true;
// (we're using chaining) now animate
this.animate({
//some animation stuff
}, function() {
// once the animation is complete, set the tracker variables
beingShown = false;
shown = true;
});
}
}).mouseout(function () {
// reset the timer if we get fired again - avoids double animations
if (hideDelayTimer) clearTimeout(hideDelayTimer);
// store the timer so that it can be cleared in the mouseover if required
hideDelayTimer = setTimeout(function () {
hideDelayTimer = null;
this.animate({
//some animation stuff
}, function () {
// once the animate is complete, set the tracker variables
shown = false;
});
}, hideDelay);
});
Try applying the stop behaviour to each element that requires it e.g.
$('.faders').each(function () {
$(this).mouseover(function () {
$(this).stop();
});
});

Categories

Resources