OnMouseOut event not triggered when moving mouse fast (GWT - all browsers)
EDIT
Given your modified question and the added complexity of changing text, let's use GWT as GWT is awesome for this kind of thing!
Ok, first our very simple CSS stylesheet:
.myStyle {
background-color: blue;
}
.myStyle-clicked {
background-color: red;
}
Here a very basic Widget that does pretty much exactly what you asked (sorry for changing the text, I tested this and I'm sure it will always work even when moving the mouse extremely fast) in beautiful, simple Java (GWT) code:
private class MyWidget extends Composite {
private Label label = new Label();
private static final String originalText = "Hello world!";
private static final String clickedText = "Goodbye world!";
public MyWidget() {
sinkEvents(Event.ONCLICK | Event.ONMOUSEOUT);
label.setText(originalText);
initWidget(label);
setStyleName("myStyle");
}
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONCLICK:
addStyleDependentName("clicked");
label.setText(clickedText);
break;
case Event.ONMOUSEOUT:
removeStyleDependentName("clicked");
label.setText(originalText);
break;
}
}
}
OLD ANSWER IF YOU ARE JUST WORRIED ABOUT MOUSE_OVER AND MOUSE_OUT
The solution to this problem is to stop doing this programmatically and do it using the native browser's events handling system, which is as fast as you can get.
To do this, use the CSS hover filter. For clicking, you don't need to worry, your problem is just move-in and move-out, which as you found out, are cases where you may not be able to trust the JS to handle very well.
I think all browsers currently support this:
<!DOCTYPE html>
<html>
<head>
<style>
.tt {
background-color: blue;
}
.tt:hover {
background-color: red;
}
</style>
</head>
<body>
<div class="tt">
The content of the body element is displayed in your browser.
</div>
</body>
</html>
I tested this and it works in Chrome, FF and IE9. According to ther w3schools docs, it works also in Safari and Opera.
Mouseover and mouseout events won't trigger when mouse moves too fast?
I'm not completely certain if it affects javascript, but different mice have different polling rates (measured in Hz) and if your mouse is 1000hz and you move 1000px at a constant velocity you should pick up every pixel.
However in reality we move the mouse very fast to begin and slow down as we approach a target to improve accuracy. meaning the first 700ish pixels will have been moved faster than the 700hz could poll and so you're missing values where the mouse moved more than 1px in 1hz.
That's kinda of a dumbed down version (mainly because I don't know everything about it) but basically small-hit-targets are prone to being missed by mousing events.
You could attempt to make target-areas larger, but it still won't fix everything :)
onmouseout triggered by text - onmouseleave (ie only) functionality preferred
Am so ashamed... oh well live and learn...
preventing mouseout event for child node
That post has the answer. Hope it helps you.
jquery hover() mouseOut event not firing when mouse is moved quickly over link
I am not 100% sure but my gut feeling is, the function call to get the panel via ajax should be a callback of the hover animate function.
The way it is now, the hover animate is 'independent' of the ajax call.
I've not tried this so I might be wrong. :P
Javascript event when mouse leaves browser window
SUMMARY: This can be done cleanly by checking the relatedTarget property during the mouseout event. If relatedTarget is not a child of document, then the mouse just left the window. It's easy to do yourself, but if you don't want to, some libraries (Mootools, future Prototype..) have baked-in functionality, and others (current Prototype) have extensions available. On IE, you could instead use mouseleave, which is a non-bubbling version of mouseout.
Details:
IE has events called mouseenter and mouseleave that are non-bubbling versions of mouseover and mouseout. Other browsers do not, but if they did, setting a mouseleave listener on window or document would do the trick.
A gentleman named Ken Snyder comes to the rescue:
On a mouseover, the relatedTarget
property references the node from
which the pointer came. On a mouseout,
the relatedTarget property references
the node to which the pointer went.On
any event, the scope is the node to
which the event is attached.When the
relatedTarget is a not child of the
currentTarget, a mouseover event is
equivalent to a mouseenter event and a
mouseout event is equivalent to a
mouseleave event.
-- http://kendsnyder.com/archives/6-MouseEnter-and-MouseLeave.html
This makes it possible to implement mouseenter and mouseleave in other browsers. In fact, Ken provides same Prototype code to do so: http://kendsnyder.com/sandbox/enterleave/MouseEnterLeave.js
Duroth pointed out in comments that MooTools already includes something similar. (Thanks Duroth.) It sounds like the upcoming Prototype release (1.6.2) may include this functionality, but I can't find anything definite.
Move active element loses mouseout event in Internet Explorer
The problem is that IE handles mouseover
differently, because it behaves like mouseenter
and mousemove
combined on an element. In other browsers it's just mouseenter
.
So even after your mouse has entered the target element and you've changed it's look and reappended it to it's parent mouseover
will still fire for every movement of the mouse, the element gets reappended again, which prevents other event handlers from being called.
The solution is to emulate the correct mouseover
behavior so that actions in onmouseover
are executed only once.
$("li").mouseover( function() {
// make sure these actions are executed only once
if ( this.style.borderColor != "red" ) {
this.style.borderColor = "red";
this.parentNode.appendChild(this);
}
});
Examples
- Extented demo of yours
- Example demonstrating the
mouseover
difference between browsers (bonus: native javascript)
Struggling with onmouseover and onmouseout
var introEl = document.getElementById("intro");
//display large div by default and
//use small div with js enabled
window.onload = function(){
introEl.className = "small";
}
function largeDiv(){
console.log("It Worked");
};
function smallDiv(){
console.log("Mouse Out!");
};
introEl.onmouseover = largeDiv; // here you don't need "()" with your defined functions
introEl.onmouseout = smallDiv; // here you don't need "()" with your defined functions
Related Topics
How to Create a Mobile Friendly Website [Infrastructure]
Bootstrap: Horizontal Fields Inside Vertical Form
CSS3/HTML 5/Png Blur Content Behind Element
How to Make a Div Fill The Remaning Vertical Space Using CSS
Timing Within a CSS Image Slider
How to Specify The System's Default Serif and Sans-Serif Font-Family
Where Should I Use CSS Vendor Prefixes
How to Override Material UI .Muicontainer-Maxwidthlg
Why Doesn't The Wrapper Div Wrap The One and Two Divs? (In Firefox Browser)
How to Use Calibri Font in Linux and Mac
Three Column Div Layout Dynamics; Left = Fixed, Center = Fluid, Right = Fluid
Windows Phone 8 HTML5 Viewport Is Higher Than The Screen After Update to 8.0.10328.78
Bootstrap Styles Missing After Deploy to Heroku