Javascript event when mouse leaves browser window [duplicate]
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.
Using only javascript, no prototype or jquery etc.
<html><head><script type="text/javascript"> var mouseX = 0; var mouseY = 0; var counter = 0;var mouseIsIn = true;function wireEvent() {window.addEventListener("mouseout", function(e){ mouseX = e.pageX; mouseY = e.pageY; if ((mouseY >= 0 && mouseY <= window.innerHeight) && (mouseX >= 0 && mouseX <= window.innerWidth)) return; //do something for mouse out counter++; mouseIsIn = false; document.getElementById('in_out').innerHTML='out' + counter; }, false);window.addEventListener("mouseover", function(e){ if(mouseIsIn) return; //do something for mouse over counter++; mouseIsIn = true; document.getElementById('in_out').innerHTML='in' + counter; }, false);}</script> </head><body onload="wireEvent();"><div id="in_out"> </div><div style="width:300px; height: 200px; background: red;">Dummy element</div></body></html>
UPDATE:
Added check for mouse position on mouseout
triggered when moving in/out elements within the body. If it's within the window, mouseout
event is not triggered.
Also introduced a flag for current status of mouse 'in' or 'out' using mouseIsIn
. If it is true
, mouseover
will not trigger too.
Perhaps you can set a listener for mouseover and mouseout document
, body
or some other element that wraps the entire document, and use that (by saving that it happened) as a trigger to determine whether it is a valid mouseout on window?
Failing that, your first idea (regarding position check) should work pretty good. Any event passes along the X/Y the event occured. If it is anything farther than height/width of the window, you left the actual window. If it is negative anything, you left the window. And, possibly, if it is exactly the height/width or exactly top: 0 or left: 0, then you left the window.