ChatGPT解决这个技术问题 Extra ChatGPT

如何禁用由子元素触发的 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() } );
Without jQuery version 这个问题

J
Jeff Ward

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

使用最新版本的 jQuery 执行此操作的最简单方法是使用 mouseentermouseleave 事件而不是 mouseovermouseout

您可以使用以下方法快速测试行为:

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

帮助了我的非 jquery javascript 相关问题。我在事件侦听器中使用 mouseenter/mouseout 而不是 mouseleave!
为了搜索,这些鼠标事件行为等同于 AS3 中的 ROLL_OVERROLL_OUT
省了我一些头痛。奇怪的是,悬停在子元素上会触发父级的 mouseout 事件,而实际上它仍在父元素内。
R
Ryan McGeary

为简单起见,我将重新组织 html 以将新显示的内容放入 mouseover 事件绑定到的元素中:

<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,但这样做是为了让示例更易于理解。


这确实是一个非常简单和干净的解决方案。谢谢你提醒我。但是在我的具体情况下,这与问题并不完全一样,这不是一个选择。不过谢谢!
在尝试了其他人在 SO 描述的不同方法之后,我回到了你的方法并让它在我的情况下工作。耶! :-)
L
Lord Nighton

是的,伙计们,使用 .mouseleave 而不是 .mouseout

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

甚至可以将它与 live 结合使用:

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

Y
Yuval Adam

您正在寻找与 javascript 的防止事件冒泡等效的 jQuery。

看一下这个:

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

基本上,您需要在子 DOM 节点中捕获事件,然后停止它们在 DOM 树上的传播。另一种方法,虽然实际上没有被建议(因为它可能会严重干扰页面上的现有事件),但将事件捕获设置为页面上的特定元素,它将接收所有事件。这对于 DnD 行为等很有用,但绝对不适合您的情况。


这可以正常工作,不知道为什么您无法正常工作.. 只是一个信息,文档链接已更改,新链接是 docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29
佚名

我只是检查鼠标坐标是否在 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
    }
}

为了可读性而减少的代码不能开箱即用。


A
Antoine

我通过在我的子元素 css 上添加 pointer-events: none; 解决了这个问题


这在修复一些使用 mouseover 和 mouseleave 事件构建自己的弹出框的遗留代码时确实有很大帮助
是的,这是最优雅的解决方案。
但是,它也禁用了点击事件,这不一定是需要的,但它仍然可以。
u
user37731

我同意瑞恩的观点。

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

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


我完全同意将 hide 放在 document.ready 事件中。内联 CSS 只是以尽可能简单的方式传达一个完整的工作示例。我将编辑我的回复以明确这一点。
K
Kibbee

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


是的,我刚刚实施了这样的解决方案。这是一个非常普遍的问题。我真的很好奇还有什么其他解决方案......谢谢你的回答!
E
Erenor Paz

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

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