如何禁用子元素触发的mouseout事件?

问题描述:

让我详细描述问题:如何禁用子元素触发的mouseout事件?

我想显示一个绝对定位的div时,悬停在一个元素上。 jQuery非常简单,工作得很好。但是当鼠标移过其中一个子元素时,它会触发包含div的mouseout事件。当鼠标悬停子元素时,如何保持javascript不触发包含元素的mouseout事件。

什么是最好的和最短的方式来做到这一点与jQuery?

下面是一个简单的例子来说明我的意思:

HTML:

<a>Hover Me</a> 
<div> 
    <input>Test</input> 
    <select> 
    <option>Option 1</option> 
    <option>Option 2</option> 
    </select> 
</div> 

的Javascript/jQuery的:

$('a').hover(function() { $(this).next().show() } 
       function() { $(this).next().hide() }); 
+0

[没有jQuery版本](http://stackoverflow.com/q/4697758/2065702) – 2016-02-09 20:49:18

这个问题有点老了,但我前几天碰到了这个问题。

最近版本的jQuery最简单的方法是使用mouseentermouseleave事件,而不是mouseovermouseout

您可以快速测试的行为:

$(".myClass").on({ 
    'mouseenter':function() { console.log("enter"); }, 
    'mouseleave':function() { console.log("leave"); } 
}); 

为了简单起见,我只想重新组织的HTML一将新显示的内容放入鼠标悬停事件绑定的元素中:

<div id="hoverable"> 
    <a>Hover Me</a> 
    <div style="display:none;"> 
    <input>Test</input> 
    <select> 
     <option>Option 1</option> 
     <option>Option 2</option> 
    </select> 
    </div> 
</div> 

然后,你可以做这样的事情:

$('#hoverable').hover(function() { $(this).find("div").show(); }, 
         function() { $(this).find("div").hide(); }); 

注:我不建议内联CSS,但它做的目的是使示例更容易消化。

+0

T他的确是一个非常简单和干净的解决方案。谢谢你提醒我。但在我的具体情况中,这与问题不完全相同,这是一种选择。虽然谢谢! – 2008-12-08 20:51:21

+0

在尝试了其他人在这里介绍的不同方法后,我回到了你的方法,并使其适用于我的情况。好极了! :-) – 2008-12-09 17:13:48

我通常看到的处理方式是在从HoverMe元素移动鼠标之间延迟约1/2秒。将鼠标移动到悬停元素中时,您需要设置一些变量,表示您将元素悬停在该元素上,然后基本上停止隐藏部分,如果设置了此变量。然后,您必须从悬停元素中添加类似的隐藏功能OnMouseOut,以便在您移除鼠标时使其消失。对不起,我不能给你任何代码,或更具体的东西,但我希望这指出你在正确的方向。

+0

是的IDD我刚刚实施了这样的解决方案。这是一个非常普遍的问题。我真的很好奇,有什么其他的解决方案...谢谢你的回答! – 2008-12-08 20:45:07

我只是检查鼠标坐标是否在mouseout事件的元素之外。

它的工作原理,但它的很多的代码,这么简单的事:(

function mouseOut(e) 
{ 
    var pos = GetMousePositionInElement(e, element); 
    if (pos.x < 0 || pos.x >= element.size.X || pos.y < 0 || pos.y >= element.size.Y) 
    { 
     RealMouseOut(); 
    } 
    else 
    { 
     //Hit a child-element 
    } 
} 

代码上剪下来的可读性,将不工作的开箱。

+0

嗯我也想过这个。这感觉有点肮脏......但它非常直截了当。 – 2008-12-08 20:47:29

您正在寻找的jQuery JavaScript的等效防止事件冒泡

检查了这一点:

http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29

基本上你需要捕获子节点DOM节点中的事件,并在那里阻止它们在DOM树上的传播。另一种方式,虽然没有建议(因为它可以严重混淆网页上的现有事件),但是将事件捕获设置为页面上的特定元素,并且它将接收所有事件。这对于DnD行为等非常有用,但绝对不适合您的情况。

+0

我一直都知道这应该是干净的方式来做到这一点,但我无法得到它的工作。将研究文档更好。谢谢! – 2008-12-08 20:49:05

+0

这是因为它应该,不知道为什么你不能得到它的工作..只是一个信息,文档的链接已经改变,新的链接是http://docs.jquery.com/Events/jQuery.Event #event.stopPropagation.28.29 – zappan 2009-03-02 11:02:18

我同意瑞恩。

您的问题是“下一个”div不是A的“子”。HTML或jQuery无法知道您的“a”元素与DOM中的子div相关。将它们包装起来并在包装上悬停意味着它们相关联。

请注意,他的代码与最佳实践不符。不要在元素上内嵌隐藏的样式;如果用户具有CSS但不包含JavaScript,则元素将隐藏并且将无法显示。更好的做法是将该声明放入document.ready事件中。

这是一个老问题,但它永远不会过时。正确的答案应该是bytebrite给出的答案。

我只想指出mouseover/mouseout和mouseenter/mouseleave之间的区别。你可以阅读一个很好的有用的解释here(进入工作演示页面的最底部)。当您使用mouseout时,当鼠标进入另一个元素时,即使它是一个子元素,事件也会停止。另一方面,当您使用mouseleave时,鼠标悬停子元素时不会触发事件,这是OP想要实现的行为。

叶氏,伙计们,用.mouseleave代替.mouseout

$('div.sort-selector').mouseleave(function() { 
    $(this).hide(); 
}); 

甚至结合live使用它:

$('div.sort-selector').live('mouseleave', function() { 
    $(this).hide(); 
}); 

我加入我的子元素pointer-events: none; CSS

解决了这个问题