时髦的jQuery mouseleave行为

我有一个类似菜单的下拉容器,它通过绑定“mouseleave”事件来隐藏。

1 2 3 4 5

我遇到的问题是我的容器的子元素包含一个SELECT对象,其中SELECT的OPTIONS物理地扩展到容器的边界之外。 因此,将鼠标hover在边界之外的OPTIONS上会触发“mouseleave”事件以触发并关闭我的下拉。 SELECT是容器的子项,因此在这种情况下,我希望mouseleave事件能够识别它。

Blocka解决方案的更新,因为它无法正确使用Firefox:

 if ((typeof e.fromElement != 'undefined' && !e.fromElement.length) || (typeof e.fromElement == 'undefined' && e.target.tagName != 'SELECT')) { // perform your mouseleave logic } 

一个非常简单有效的解决方案是在执行操作之前控制鼠标指针坐标。 如果容器焦点聚焦在元素“select”上,则检查指针。 如果指针位于容器内,则它不执行任何操作,但是如果这是容器元素,则执行操作

  $('#div_solapa_lateral').bind("mouseenter",function(){ $(this).animate({left:'0'},500); }); $('#div_solapa_lateral').bind("mouseleave",function(e){ if ( e.clientX>360 || e.clientY<60 || e.pageY>625 ) $(this).animate({left:'-320'},500); }); 

clientX和clientY为“ position:relative; ”pageX和pageY为“ position:absolute;

谢谢没有眼皮! 我昨晚发现了这个问题的另一个答案,与你发布的内容非常相似。

 .bind("mouseleave", function(e) { // ANSWER HERE!!! if (!e.fromElement.length) { _state.filterTrigger.data("open", false); setTimeout(function() { _toggleFilter(_state.filterTrigger); }, 2000); } }); 

e.fromElement对象提供SELECT中OPTION对象的计数。 其他HTML标记未定义此对象。 我还没有尝试过你的解决方案,但这对我也有用。

也许当下拉列表扩展时,你可以设置一个标志。 选择项目时清除标志。 发生鼠标移动时,除非标志清除,否则不要隐藏菜单。

我总是对这种程度的黑客UI事件感到紧张,因为很可能你最终会把某个浏览器留在一个完全无法使用的状态。

大多数渲染器(除了Gecko,我认为都是)在一个单独的“窗口”中实现打开的菜单及其选项,而不是页面上的元素。 然后,该页面不一定知道用户与打开的菜单的交互。 你不可能在所有主流浏览器中达到预期的效果……

编辑:……但也许如此。 这适用于Safari和Firefox。 我现在无法在IE中测试,但请试一试:

 var timer; $('#container').mouseleave(function(e) { if($(e.target).parents('#container').length) { return; } timer = setTimeout(function() { $('#container select').blur(); }, 50); }).mouseenter(function(e) { if(timer) { clearTimeout(timer); } }); 

编辑2:实际上,当 “window”打开时,Safari根本不会触发mouseleave (或mouseout )。