为什么我不能可靠地捕捉到鼠标事件?

我需要知道鼠标光标何时离开div 。 所以我连接了mouseout事件。 但是,如果我非常快速地将鼠标移出div ,则mouseout事件不会触发 。 这是正确的:鼠标光标静止在div ,现在在div ,但是mouseoutcallback没有被调用。 (如果我不移动鼠标的话,它工作的很好。)

顺便说一句,在最新的谷歌浏览器中是这样的 – 所以不只是一个“旧的浏览器”的问题。

解决方法:

关于这个问题的一个问题已经提出过了 。 显然这只是一个生活中的事实,唯一的解决方法是我手动监视mousemove事件,每次检查光标的x / y坐标,看看它们是否落入div的边界框,所以你有如果光标不在其中,则有更多机会“注意”。

与让浏览器本身执行所有这些操作相比,对每一个像素移动进行计算都有一定的性能影响。 编码也很繁琐。

在我的问题上…

为什么浏览器不能可靠捕捉到mouseout事件? 如果我可以可靠地告诉鼠标何时离开div使用上述解决方法,为什么浏览器不能做到这一点?

我明白(从上面链接的答案),JavaScript不尝试插入“框架”。 假如你把一个鼠标移动处理程序放在document ,并快速将鼠标向右移动一个完美的水平线,你可能不会得到200个mousemove事件。 less数将被错过。 我没有这个问题。

但是,如果在鼠标穿越div的边界时错过了某些像素运动,为什么还要忽略mouseout事件呢? 当浏览器终于​​开始重新注册鼠标的位置时(突然快速移动之后),即使鼠标现在在盒子外面数英里 ,重点是它曾经是在盒子里,不再是 。 那么为什么不呢然后发生鼠标事件呢?

我只是不明白为什么这将是浏览器供应商解决的一个难题。 (但是我相信可能有一个很好的理由,我觉得这太愚蠢了。)

我主要是出于好奇,发布这个问题,但我希望答案可能会提供一些洞察力,可以帮助我更有效地解决问题。 此外,任何替代解决方法(比上面提到的更快)将受到欢迎。

我知道你不想要一个解决方法,但是你不需要检查鼠标的x / y来知道你是否在一个元素中。 您可以简单地检查mousemove事件触发的元素。 如果你把一个鼠标移动到文档上,这个事件将会从它的一个子元素中触发,你可以把这个元素和你的元素进行比较,以确定它是否是它的后代之一。

或者你可以上去父节点树,并停止,如果你find你的元素。 然后你知道你在元素里面,还在里面,否则你到达文档,你就出来了。

有些浏览器实现了mouseenter / mouseleave事件,我注意到它比mouseout更精确。 原型和jQuery有没有实现这些新事件的浏览器的解决方法。 Mouseleave不会从元素的子元素中触发,而mouseout则会触发。

你描述很快移动鼠标。 当你停下来的时候,指针还在页面内吗? 也就是说,你的鼠标指针是否仍然hover在可见网页的某个部分?

如果它已经到了外面,那么浏览器应该做什么也不一定清楚。 mouseout事件应该有一个relatedTarget属性来定位鼠标指针已经进入的内容。 如果鼠标指针已经在页面区域之外,则没有相关的目标指向。

换句话说,当鼠标离开页面区域时,浏览器停止跟踪并停止报告其位置。 如果你移动鼠标足够快,从浏览器的angular度来看,鼠标就消失了。 直到您将鼠标移回到浏览器知道它在哪里的可浏览页面的边框中,然后触发所有适当的基于移动的动作(如鼠标移出)。

我遇到了这个问题几次,我接受了这个问题作为生活中的事实。 但取决于你的需求,你可以像我一样使用CSS。 例如,如果我只想显示/隐藏另一个元素的元素,那么CSS就是要走的路。 这是一个可靠的例子:

 .large { width: 175px; height: 175px; position: absolute; border-radius: 100%; /*hide the glass by default*/ top: -9999px; left: -9999px; opacity: 0; transition: opacity .2s ease-in-out; z-index: 100; pointer-events: none; } .small:hover + .large { opacity: 1; } 

http://codepen.io/tanduong/pen/aBMxyd

  1. 为什么浏览器不能可靠捕捉到鼠标事件? 如果我可以可靠地告诉鼠标何时离开div使用上述解决方法,为什么浏览器不能做到这一点?

    我想你说的时候你自己回答了这个问题:

    与让浏览器本身执行所有这些操作相比,对每一个像素移动进行计算都有一定的性能影响。

    浏览器不会在帧之间进行插值,因此,正如您所说的那样,它会要求更多的资源和内存,这可能就是为什么它不是“固定”的原因。

  2. 如果在鼠标穿越div的边界时错过某些像素运动,为什么还要忽略掉鼠标事件呢? 当浏览器终于​​开始重新注册鼠标的位置时(突然快速移动之后),即使鼠标现在在盒子外面数英里,重点是它曾经是在盒子里,不再是。 那么为什么不呢然后发生鼠标事件呢?

    我不知道,但我不认为这是“现在,现在已经出来”的状况。 相反,它是否跨越边界(如果MouseX - ElemOffsetX= 1 )。 我同意,它没有多less意义,但可能是因为如果您将值设置为> 1它会多次触发事件。 否则,它将不得不跟踪事件,这是不属于JS性质,看它是如何添加事件asynchronous堆栈。


你可以尝试使用jQuery的mouseleave事件 。 这样做有两件事延迟了事件的解除:

  1. 它遍历DOM树,看它是否真的离开了元素
  2. 我认为它实现了一个超时调用,它应该解决你注意到的插值问题。

我发现你的问题,缺乏其他明确的答案有用,因为它告诉我,我必须创build一个解决方法。 我使用了你的问题和其他贡献者提出的想法。

我有同样的问题,当我使用jquery mouseleave elem.bind('mouseleave',data,mouseLeavesZon​​e);

问题是间歇性的,可能与客户端上的繁忙CPU有关。 比方说,当鼠标移出一个div时,CPU在其他地方就很忙。 那么这可能是错误的原因似乎是合乎逻辑的。 我同意; 这应该由浏览器供应商来解决。

http://jsfiddle.net/bgil2012/gWP5x/1/

(另外:我的JQuery代码需要使用较老的jQuery方法,因为它必须在运行jQuery 1.4的Drupal 7中运行,而不需要应用即将发布的补丁)。