Reputation: 1054
I have a mouseover / mouseout handler. Both use Javascript timeout to delay their job. But mouseout event triggers even when mouse is still over the selector. It works normally when timeout is turned off in mouseout script. So I suppose I do something wrong about timeout. It is something like
$('.selector').live( {mouseover : function() {
var timeout = setTimeout(function() {
$('.something' ).show();
}, 1000);
}, mouseout: function () {
timeout = setTimeout(function() {
$('.something' ).hide();
}, 2000);
}
});
Same thing happens if I use hover handler instead of mouseover / mouseout. And same thing if I use different variable names for two timeouts, or if I clear one timeout before calling another. What do I do wrong?
Upvotes: 0
Views: 431
Reputation: 140236
Since it works normally without timeouts I assume mouseover/mouseout is the correct event for you instead of mouseenter/mouseleave.
You are calling multiple timeouts constantly which are firing all over the place, you need to use a single timer that is only timing a single thing at one time:
(function () {
var timeout = 0;
$('.selector').live({
mouseover: function () {
window.clearTimeout( timeout );
timeout = setTimeout(function () {
$('.something').show();
}, 1000);
},
mouseout: function () {
window.clearTimeout( timeout );
timeout = setTimeout(function () {
$('.something').hide();
}, 2000);
}
});
})()
window.setTimeout
just returns an ordinary integer number. Each time you call window.setTimeout
a new timer will be created regardless of what variable the return value is assigned to. The return value of window.setTimeout
can be used to clear a specific timer.
As a side effect, you can clear timeouts that you don't even know are existing. For example:
jQuery("div").fadeOut( 15000 );
var l = 10000;
while( l-- ) window.clearTimeout( l );
You are brute forcing 10000 different timer ids and clearing them all, taking out the jQuery fx internal timer which stops the fading out. Do not use in real code, for demonstration purposes only.
Upvotes: 2
Reputation: 18557
You should clear the timeout so they don't overlap.
var timeout = null;
$('#foo').live({
mouseover: function() {
if(timeout !== null){
clearTimeout(timeout);
timeout = null;
}
timeout = setTimeout(function() {
$('#bar').show();
}, 1000);
},
mouseout: function() {
if(timeout !== null){
clearTimeout(timeout);
timeout = null;
}
timeout = setTimeout(function() {
$('#bar').hide();
}, 2000);
}
});
demo: http://jsfiddle.net/46mFc/1/
Upvotes: 0