How do I add a delay to the mouseover function? - javascript

I'm making a calendar app using the jQuery plugin FullCalendar and I made a tab to the left of the calendar with the weeks from 1-6 on it. When the user drags their mouse over one of the weeks the calendar switches to the view of the respective view. This works but it can be annoying for the user if they do it accidentally. So, I want to add a delay to the function so that it will only happen if the user has their mouse on it for a few hundred milliseconds so it will happen less without the user wanting it to happen.
$('#week3').mouseover(function() {
$('#week3').css('color', 'white');
$('#week3').css('background-color', '#6B8BA9');
$('#week3').week3();
I want to add a short delay before $('#week3').css('color', 'white');

If I am understanding you correctly, then you will need a more complete solution like below
var mouse_monitor
$('#week3').mouseover(function() {
mouse_monitor = setTimeout(function(){
$('#week3').css('color', 'white');
$('#week3').css('background-color', '#6B8BA9');
$('#week3').week3();
}, 1500)
});
$('#week3').mouseout(function() { clearTimeout( mouse_monitor ); }
The var mouse_monitor is a global reference to your timeout function. The mouseout function is missing in other post, which assures that your mouseover function will not fire if the user moves the mouse off the hover target before the value of the setTimeout expires. Other examples will still invoke your mouseover function everytime, but with just an added delay, so they won't work for what I think you are trying to achieve.

Use a timeout :
$('#week3').on({
mouseenter: function() {
var that = this;
$(that).data('timer',
setTimeout(function() {
$(that).css('color', 'white');
},1000)
).css('background-color', '#6B8BA9').week3();
},
mouseleave: function() {
clearTimeout( $(this).data('timer') );
}
});

you are looking for setTimeout

Related

How to avoid duplicate each loop in jquery?

I had a function that looks like this
function show_services_title(show_services){
$('.service').fadeOut();
$.each($('.service'), function(i) {
$(this).delay(500*i).fadeIn();
});
}
Now, this functions is invoked when I click on a link, the problem is that when I click the link the function start to show each div with the class 'service', but when I click the link again and the divs haven't finish showing yet then occur a mess in the screen.
Here is an example that simulate the behavior I'm trying to describe and I want to avoid.
http://jsfiddle.net/bw7jn/4/
Try to disable running the animation the second time when the previous animation is still running.
$(document).ready(function(){
$('#link').click(function(){
show_services_title();
});
});
function show_services_title(show_services){
//if we're already animating, don't start a new one
if($('ul').attr('data-animating') != 'true'){
//make sure other clicks dont trigger this animation
$('ul').attr('data-animating', 'true');
$('.service').fadeOut();
$.each($('.service'), function(i, element) {
setTimeout(function(){
$(element).fadeIn();
//check if this is the last element we're gonna animate
if(i == $('.service').length-1){
//animation is done, allow new animations to start
$('ul').attr('data-animating', 'false');
}
}, 500*i);
});
}
}
http://jsfiddle.net/bw7jn/7/

why setInterval() cycle goes faster every time?

I'm building a custom slider on Javascript , and I want that every time the user clicks on a div of the slider, the slider should stop for X seconds.
My code is:
$(document).ready(function () {
var ciclo;
var index_slide = 1;
function startSlidercicle() {
ciclo = setInterval( function() {
// Slider code goes here
}, 3000);
}
//Here I start the slider animation
startSlidercicle();
//When the user clicks on a div called 'slide', stop the cycle and start again the animation cycle
$('.slide').on('click', function() {
clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);
});
});
But the problem is that everytime I click and stop the slider, the cycle starts faster and faster. How can I fix it?
Instead of:
clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);
or:
clearInterval(ciclo);
setTimeout(startSlidercicle, 3000);
I changed the code to be:
clearInterval(ciclo);
startSlidercicle();
And now the slider just works fine. I think that, in the first two proposals, every time I click on the div, a new function is created, "overlapping" over the existing cycle and, thus, it looks like the slider speeds up, but its just one cycle starting over another.
You need to change this:
clearInterval(ciclo);
setTimeout(startSlidercicle(), 3000);
to this:
clearInterval(ciclo);
setTimeout(startSlidercicle, 3000);
In your existing code, you are calling startSlidercirle immediately and it is not waiting until the setTimeout() fires because you have the () after the function name. That means to execute it immediately and pass the result of executing that to setTimeout(). You want to just pass the function reference to setTimeout() which is done by just having the name of the function with no () after it. This is a common mistake.

jQuery: Prevent stacking animations

I know there are several other posts with solutions to this, but my current problem is a little different.
I have two events on an element - mouseenter and mouseleave. The first changed the color of my element to light and the other back to dark, this makes a flashing effect.
The problem is when I go in and out a couple of times the events stack and it flashes many times even if no new events are triggered. I would like to prevent that, but .stop() does not help.
Here's the catch: I would like to trigger 1 flash no matter what, but not more than 1. So when someone moves in / out - the event mouseenter will be fired, after it mouseleave and after it nothing.. until another in / out is triggered.
I guess this could be made by locking (not listening for) new events when in / out is triggered up until the effect has finished, but I don't know how to do without unbinding and binding it again. Isn't there any lockEvent() or something?
Have you already used .stop(true) or .stop(true, true)?
there is pseudo-class in jQuery ":animated"
you can use it on first mouseenter even like:
if ( $(this).is(':animated')) {
return false;
}
to prevent additional animation
You can try just setting a bool var and firing only if false...
var anim = {
animating: false,
over: function(){
if(!anim.animating)
{
anim.animating = true;
// do you animation here
// and set your animating bool to false before calling outro...
$('#elem').animate({/*some css change*/ }, 1000, function(){
anim.animating = false;
anim.out();
});
}
},
out: function(){
if(!anim.animating)
{
anim.animating = true;
//do your outro animation here
$('#elem').animate({/*some css change*/ }, 1000, function(){
anim.animating = false;
});
}
}
};
then have your listener call anim.over and anim.out...
$('#elem').on('mouseenter', function(){
anim.over();
}).on('mouseleave', function(){
anim.out();
});
This way you will call animation on enter and it will automatically fire off the outro animation when the intro completes.

Stop duplicate mouse over detection

I have a popup that is executed on mouseover with jquery.
Within that function I have a second delay before the popup displays using settimeout
Problem is if in that second they mouse over multiple times then multiple popups are triggered.
$('#div').mouseover(function() {setTimeout("popup()",1000);});
What I need to do is disable the detection and then re enable it in popup().
How might I do that?
You can use .hover() with a clearTimeout(), like this:
$('#div').hover(function() {
$.data(this, 'timer', setTimeout(popup, 1000));
}, function() {
clearTimeout($.data(this, 'timer'));
});
This clears the timeout you're setting if the mouse leaves, you'll have to stay on the element for a full second for the popup to trigger. We're just using $.data() on the element to store the timer ID (so we know what to clear). The other change is to not pass a string to setTimeout() but rather a reference directly to the function.
I guess something like this
(function(){
var popup_timer = 0;
$('#div').mouseover(function() {
clearTimeout(popup_timer);
popup_timer = setTimeout("popup()",1000);
});
});
EDIT updated code, clearTimeout added, wrapped

Jquery - Delay mouseout event

Is there a way to make jQuery wait a certain about amount of time before mouseout event is fired?
It is firing too early at the moment and I'd prefer to wait 500ms before it evaluates the mouse out. An example of the code I'm using below.
$('.under-construction',this).bind({
mousemove: function(e) {
setToolTipPosition(this,e);
css({'cursor' : 'crosshair' });
},
mouseover: function() {
$c('show!');
showUnderConstruction();
},
mouseout: function() {
$c('hide!');
hideUnderConstruction();
},
click: function() {
return false;
}
});
Is there a jQuery way to do this or will I have to do it myself?
Split the logic inside the mouseout into another function. in the mouseout even call this function with a setTimeout("myMouseOut", 500). And you can combine the mouseover event with a clearTimeout() to reset the timer if the user moves into a new element.
You could always wrap your logic in a setTimeout() function.
mouseout: function() {
setTimeout(function(){
$c('hide!');
hideUnderConstruction();
}, 500);
}
You might check out the hoverIntent plugin lets you define some vars that help with mouseenter/out interactions

Categories

Resources