Yes, I know this question has been asked before, but I can't find an answer that works. This is an accepted answer from one of the other questions:
$('#element').hover(function()
{
$(this).data('timeout', window.setTimeout(function()
{
alert('hovered for 2 seconds');
}, 2000));
},
function()
{
clearTimeout($(this).data('timeout'));
alert('mouse left');
});
http://jsfiddle.net/nCcxt/
As you see it doesn't do what it's supposed to.
What I need is simple in theory but I can't get it to work - when a user hovers over a link for 2 seconds, a function is called. If the user moves the mouse away before 2 seconds pass, nothing happens.
The code works perfectly fine. It only breaks due to the alert() calls which causes the mouseout event to be triggered.
What do we learn from it? Do not use alert() in combination with focus/hover/mousemove-related events.
By the way, there are already jQuery plugins available for what you want to do: http://cherne.net/brian/resources/jquery.hoverIntent.html
Related
jsFiddle
I use a customized drop-down menu which runs on jQuery events and animations.
The problem occurs when I activate the drop-down via mouseenter several times, which results in the menu sliding down then sliding up several times. I tried to fix it by adding .stop(true), which was successful, but it resulted in other problems like this.
I followed that advice(jsFiddle Here), but it causes more unattractive problems.
I need is a way to stop a function from firing redundantly, but still be able to stop a "slide down" immediately and then "slide up" if the user triggers .mouseleave.
I tangled with custom queues for a good 5 hours, with no success :(
Any ideas, advice, and criticism is welcome.
Basically it boils down to delaying the execution of the event handler.
var mouseoverTimer = null;
$('.elem').mouseover(function(){
clearTimeout(mouseoverTimer); //ignore previous trigger
mouseoverTimer = setTimeout(function(){ //wait to execute handler again
//execute actual handler here
}, 10);
});
If the same handler was called within the specified interval the pending execution is cancelled and queued again to execute 10ms later hoping that there's no subsequent trigger within that interval.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Throttle event calls in jQuery
I like the .change() functionality of jQuery, but I'd like to prevent triggering a ton of AJAX requests when a user quickly changes options in a select drop down. As an example, when a user uses a mouse scroll wheel, it will trigger each options as they pick their new option.
I'd like to come up with a good clean way to handle only sending these updates once the user stops updating the select dropdown a second.
Is there a neat way of handling this situation?
The typical way to do this is with a setTimeout and clearTimeout:
var wto;
$('#select').change(function() {
clearTimeout(wto);
wto = setTimeout(function() {
// do stuff when user has been idle for 1 second
}, 1000);
});
I recommend you to use underscore.js then:
var newFunction=_.debounce(function (){
alert('You function, after use stop scroll')
},1000); //Wait seconds after he stops
$('#select').change(newFunction);
Read more about underscore.debounce.
I have a problem involving setinterval. It's probably best to show an example so here's a link here:
http://boudaki.com/testing/carouselTest
Basically I'm having problems making this work like I need it to. When the page loads the content rotates every three seconds and the numbered buttons on the right do so also. when you click on a button the buttons extend and the animation is stopped - all good. Then when you click the little close button at the bottom of the buttons the animation resumes - all good....but then when you come to click on the numbered buttons again the animation keeps on going. Why?
There's rather a lot of code but the setIntervals and clear intervals are:
line 69: on document.ready start the animation off -assign timerId to a global var
line 87: When the user clicks on the numbered button clearinterval in that animation
line 102: when the user clicks on the close button start the animation again
That's it....I just don't get why it doesn't stop the animation the second time around??? Can anyone see why?
Any ideas?
This is a guess, but try bringing all your functions and variables into the $(document).ready(function() {...}) call.
Then change your setInterval() so that you're passing in a reference to the function instead of a string for eval:
timerId = setInterval( rotateForward, 3000 );
Be sure to change all of them.
To be honest I don't know why this would work, but making the variable local may help to ensure that we're dealing with only one version of timerId.
$closeButton.click(function() { ... }); is inside of your loop. That handler is getting added 4 times, so when you click close, 4 timers are added and only 1 is cleared when you open the menu again.
I think the problem is the scoping of timerId. Try changing alert('should stop now'); to alert('should stop now' + timerId);
I'll bet you'll find that timerId is always the same value.
The only thing I can think of is... I'm pretty sure you can't put the () inside the setInterval call. It does seem to work at first, but maybe that's part of the issue? Hard to say... but I'd at least start there.
setInterval("rotateForward", 3000);
Also, maybe try calling the clearInterval every time before you start it.
I need to initiate the event handler after 3 seconds of being focused on an image. How should I go about it?
Also, I need to trigger another event handler, when I am at a particular part of an image, say the approximate middle of the image. How do I do this?
Use javascript's setTimeout and setInterval functions.
// alert after 2 seconds
setTimeout("alert('Hello World!')", 2000);
// alert every 2 seconds
setInterval("alert('Hello, world!')", 2000);
JavaScript
var timeout;
function message(){
alert('Hey there');
}
function start(){
timeout = setTimeout(message,3000);
}
function stop(){
clearTimeout(timeout);
}
HTML
<img src="HappyCow.jpg" onmouseover="start()" onmouseout="stop()" />
The event handling is rough here (inline >.<), but I think this gets you started.
For question #1: look into timers - you'd start it when the image is in focus (or the mouse hovers over it etc.), then it calls a function after 3 seconds (or any other period). The function would handle what you want to do after three seconds. (Maybe also check if the image is still "active".)
For question #2: One way to do this is Imagemaps, but there may be other/better options.
Hope this helps!
I have a table with some columns. In each of them is a picture where I have an onmouseover/onmouseout event on it, which shows a message in a div and hides the message.
My problem is, after a user moves quickly from left to right over a lot of images, all mouseover and mouseout events of the images are executed, which looks stupid...
Is it possible to rearrange the internal event stack to avoid this, such that the user executes only the current event (mostly the first one) and then the last one, if it is not the same type?
For example, if mouseover over first image is executed and the mouse moving position stops over an image three times next to the first one. I can avoid all other events firing, because the mouse stopped over an image and the mouseover is like the one where I stopped with the mouse.
How can I avoid this multiple event firing?
You need to check out the hoverIntent plugin, which addresses this problem.
We've had the exact same problem, What we've done is on the mouseover event is to set a variable _mouseOn to true (set to false on mouseout) then set a oneTime event over that fires in say 500 ms.. The one time event will check if the _mouseOn is true and display the image
function Hover() {
_mouseOn = true;
$(document).oneTime(500, "500ms", functionToCheckTheMouseOnAndDisplayTheImage);
};
//Global timeout handle for mouseover and mouseout
var timeoutHandle;
$(document).ready(function() {
BindMouseHover($(".helptext"));
});//closing ready
//bind mouseover and mouseout actions on all elements
function BindMouseHover(elements) {
$(elements).hover(
function() {
timeoutHandle = setTimeout('HandleMouseHover(true)', 1000);
},
function() {
HandleMouseHover(false);
}
);
}
//Handle Mouseover and mouseout events
function HandleMouseHover(bDelay) {
if (bDelay) {
$(".tooltip").show();
}
else {
$(".tooltip").hide();
clearTimeout(timeoutHandle);
}
}
Explanation:
On every mouseover schedule a call to DelayedTooltip(***true*)** after 1000ms and save the setTimeout handle to timeoutHandle
If mouseout happens within that 1000ms interval then simply call clearTimeout(***timeoutHandle*)** to cancel the setTimeout
This can be easily extended to apply to many heterogeneous elements and wire the customize tooltip text based on the element hovered.
Click here to know more about JavaScript Timing Events.
You can't, and shouldn't try to, avoid the events firing. What you should avoid is your code immediately responding to them by doing something that winds up looking stupid. For example, you can have your mouseovers register, with some controller object, which image the user is currently over, and set a short timeout to the function that triggers the actual behavior (removing a previous timeout if it's already running). The mouseout unregisters the image and removes the timeout. That way, when the behavior runs, you only operate on the image that the user moused over most recently.
I think it's better (from http://bavotasan.com/demos/fadehover/, THANKS)
<script>
$(document).ready(function(){
$(".a").hover(
function() {
$(this).stop().animate({"opacity": "0"}, "slow");
},
function() {
$(this).stop().animate({"opacity": "1"}, "slow");
});
});
</script>