clearInterval() Undefined Error After Using setInterval() - javascript

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.

Related

Set delay for the second click function jQuery

I want the second click function to be delayed by 500ms, where do I insert this?
$(document).ready(function(){
$('.dropToggler').click(function() {
$(this).parent().addClass("open");
});
$('.acceptCta').click(function() { //I want the delay on this function.
$(this).parent().removeClass("open");
});
});
Tried this too, didn't work:
$(document).ready(function() {
$('.dropToggler').click(function() {
$(this).parent().addClass("open");
});
setTimeout(function() {
$('.acceptCta').click(function() {
$(this).parent().removeClass("open");
});
}, 800);
});
You need to delegate and tell which element you are referring to when clicking and use that for setTimeout - removeClass function
var $this = $(this) // will be click function
setTimeout(function() {} does not know what is $(this) as we searching for the parents of the clicked event element.
$(document).ready(function() {
$('.dropToggler').click(function() {
$(this).parent().addClass("open");
});
$('.acceptCta').click(function() {
//This needed
var $this = $(this)
//delay removeClass
setTimeout(function() {
$this.parent().removeClass("open");
}, 800);
});
});
setTimeout(function(){
//your code goes here
alert("Hello");
}, 3000);//here you can set the time in milliseconds
you can use the setTimeout Function

why javascript function stops working after returning back?

i have made a rotating slider in javascript and css. Javascript function makes it rotating. When i first time load the page it works fine but when i navigate to some other page and then return back, the js function is called but the slider does not stop rotating on mouse hover. I have made a js function that when mouse hovers on div the rotation stop, when it leaves the function is called again.Here is my js code
var timer;
window.onload = function()
{
myTimer();
};
var $i=1;
function myTimer(){
timer=setInterval(function(){
if($i<6){
closeTab();
openTab($i);
$i++;
}
else
{$i=1;}
},2000);
}
closeTab();
var selectedSlider ;
function closeTab()
{
var $this = $('#accordion > li');
//$width=$(window).width();
//$this.stop().animate({'width':'110px'},500);
$this.stop().animate({'width':'7%'},500);
$('.heading',$this).stop(true,true).fadeIn();
$('.description',$this).stop(true,true).fadeOut(500);
$('.bgDescription',$this).stop(true,true).slideUp(700);
}
function openTab(id)
{
var $this = $('.bg'+id);
//$this.stop().animate({'width':'450px'},500);
$this.stop().animate({'width':'70%'},500);
$('.heading',$this).stop(true,true).fadeOut();
$('.bgDescription',$this).stop(true,true).slideDown(500);
$('.description',$this).stop(true,true).fadeIn();
}
openTab(1);
$(function() {
$('#accordion > li').hover(
function () {
console.log("in mouse hover");
var $this = $(this);
selectedSlider = $this.attr("class").replace("bg", "");
closeTab();
openTab(selectedSlider);
clearInterval(timer);
},
function () {
}
);
});
$('#accordion > li').mouseleave(function(){
console.log("in mouse leave");
myTimer();
});
As #David said browser was caching the javascript, so your code for hover effect is not work as you put it in such a way, that when js file will call then hover event is fire but here js file is already cached.
You may try this, instead of using hover function anonymously put it inside window.onload.

Delay jQuery fadeIn due to unwanted behavior

How do I make my .right-menu DIV to fadein only after a couple of moments the mouse is hovering its parent .right-menu-background ? The thing is that when you move the cursor quickly in and out, .right-menu DIV is reappearing a lot of times after.
How do I delay animation for few ms?
Here's the code:
$(function(){
$(".right-menu-background").hover(function(){
$(this).find(".right-menu").fadeIn();
}
,function(){
$(this).find(".right-menu").fadeOut();
}
);
});
a easy fix is to use .stop()
$(function () {
$(".right-menu-background").hover(function () {
$(this).find(".right-menu").stop(true, true).fadeIn();
}, function () {
$(this).find(".right-menu").stop(true, true).fadeOut();
});
});
using timer
$(function () {
$(".right-menu-background").hover(function () {
var el = $(this).find(".right-menu");
var timer = setTimeout(function(){
el.stop(true, true).fadeIn();
}, 500);
el.data('hovertimer', timer);
}, function () {
var el = $(this).find(".right-menu");
clearTimeout(el.data('hovertimer'))
el.stop(true, true).fadeOut();
});
});
Use the stop() function in front of fading calls ...stop(true, true)
With those two parameters set to true, the animation queue is cleared and the last animation is played this will get ride of the weird effect
$(this).find(".right-menu").stop(true, true).fadeIn();
Use .delay() function.
Here is the code:
$(function(){
$(".right-menu-background").hover(function(){
$(this).find(".right-menu").delay(800).fadeIn(400);
},function(){
$(this).find(".right-menu").fadeOut(400);
});
});
Check the demo here: http://jsfiddle.net/Mju7X/

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
});
});
});
.....

clearTimeout only works at end of loop

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();

Categories

Resources