鼠标离开浏览器窗口时的Javascript事件

Geo*_*off 11 javascript safari ajax mouseout prototypejs

我想在鼠标离开浏览器窗口时运行一些Javascript代码.我只需要支持Safari(WebKit.)

我尝试在窗口上放置一个mouseout处理程序.当鼠标离开浏览器窗口时,可以可靠地调用该处理程序.但是由于冒泡,当鼠标在文档中的元素之间移动时也会调用它.我无法弄清楚如何确定鼠标何时实际离开窗口以及何时仅在元素之间移动.

当鼠标离开窗口时,只生成一个事件,并且目标元素看起来是鼠标实际上的元素.因此,检查目标元素是窗口还是文档是不起作用的.并且将整个页面包装在一个不可见的包含div中也不起作用:如果div是不可见的,那么鼠标永远不会超过它,所以没有任何变化.

(如果我把处理程序放在document或document.body上会发生同样的事情,除了令人惊讶的document.body在鼠标进入或离开窗口的空白部分时没有鼠标悬停/鼠标输出事件,例如创建空的垂直空间通过绝对定位底部元素:0.对于该空间,文档和窗口将获得mouseover/mouseout事件,目标为<html>,但document.body不会.)

我有一些想法:

  • 在每个mouseout事件中,获取鼠标的实际位置,看看它是否实际上在窗口上.但我不知道这是否真的可行,听起来消除所有竞争条件会很棘手.
  • 同时注册一个鼠标悬停处理程序,并检测鼠标悬停未进行鼠标移除(或紧接着a)鼠标悬停的情况.但这需要一个计时器.

我们使用prototype.js,所以理想情况下我想用原型的Event.observe来表达解决方案,但我可以想出那部分.

谢谢你的任何建议!

Geo*_*off 12

摘要:这可以通过在mouseout事件期间检查relatedTarget属性来干净地完成.如果relatedTarget不是文档的子项,则鼠标刚离开窗口.你自己很容易做到,但是如果你不想这样做,一些库(Mootools,未来的Prototype ......)具有烘焙功能,而其他库(当前的Prototype)则具有扩展功能.在IE上,您可以使用mouseleave,这是一个非冒泡的mouseout版本.

细节:

IE具有称为mouseenter和mouseleave的事件,它们是鼠标悬停和鼠标悬停的非冒泡版本.其他浏览器没有,但如果他们这样做,在窗口或文档上设置mouseleave监听器就可以了.

一位名叫Ken Snyder的绅士来救援:

在鼠标悬停时,relatedTarget属性引用指针所来自的节点.在mouseout上,relatedTarget属性引用指针所到达的节点.在任何情况下,范围都是事件所附加到的节点.当relatedTarget是currentTarget的非子节点时,鼠标悬停事件等效于mouseenter事件和mouseout事件相当于mouseleave事件.

- http://kendsnyder.com/archives/6-MouseEnter-and-MouseLeave.html

这使得在其他浏览器中实现mouseenter和mouseleave成为可能.实际上,Ken提供了相同的Prototype代码:http://kendsnyder.com/sandbox/enterleave/MouseEnterLeave.js

Duroth在评论中指出,MooTools已经包含了类似的东西.(感谢Duroth.)听起来即将推出的Prototype版本(1.6.2)可能包含此功能,但我找不到任何确定的内容.


o.k*_*k.w 9

仅使用javascript,没有原型或jquery等.

<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">&nbsp;</div>
<div style="width:300px; height: 200px; background: red;">Dummy element</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

更新:在移入/移出正文中的元素时
添加了对mouseout触发的鼠标位置的检查.如果它在窗口内,mouseout则不会触发事件.
还介绍了鼠标'in'或'out'使用当前状态的标志mouseIsIn.如果是true,mouseover也不会触发.