【问题标题】:Unexpected behaviour of 'onmouseout' in a "hover menu" [closed]“悬停菜单”中“onmouseout”的意外行为[关闭]
【发布时间】:2013-10-27 07:53:15
【问题描述】:

我正在尝试创建一个“悬停菜单” - 将鼠标悬停在标题上,然后在其下方出现一个菜单框 - 我希望当您将鼠标移出时它会消失。

看: http://jsfiddle.net/kzJ8y/

将鼠标悬停在“STUFF”上 - 菜单框出现在下方。现在开始在它上面慢慢移动鼠标光标 - 向下 - 一旦你通过第一个项目 - 它就会消失! 这不是想要的操作。
显然,我的 onmouseout 定义在 #menuStuff div 上 - 您可以使用 Firebug 清楚地看到它的尺寸 - 它占用整个列表的宽度和高度 -
所以....为什么从第一个列表项向下移动后会触发?光标仍在 div 的范围内 - 这是怎么回事?

【问题讨论】:

  • 问题标题很奇怪。
  • 好,我换个无聊的。
  • 这不是无聊的有趣,而是与您的问题的相关性,以便您可以从其他人那里获得更好的帮助,因为问题本身是好的。为什么让它得到否定
  • 我知道。两个版本的标题具有完全相同的含义,但第一个版本需要识别流行的互联网模因。没关系,我改了...

标签: javascript menu hover onmouseout


【解决方案1】:

如果你使用 jQuery,你可以在 div 上使用 mouseleave 事件:

http://jsfiddle.net/Kjdc5/

$('#menuStuff').mouseleave(function(){
    $('#menuStuff').hide();
});

【讨论】:

    【解决方案2】:

    使用 onmouseleave 代替 onmouseout

    <div id="menuStuff" class="hover-menu" onmouseleave="$('#menuStuff').hide();" >
    

    jsfiddle -> http://jsfiddle.net/kzJ8y/1/

    【讨论】:

      【解决方案3】:

      鼠标移出图层会导致子元素上的事件冒泡

      在基于层的导航中,您可能需要知道鼠标何时离开层以便关闭它。因此,您将 onmouseout 事件处理程序注册到该层。但是,当鼠标离开图层内的任何元素时,事件冒泡会导致此事件处理程序触发。

      --------------
      | Layer      |.onmouseout = doSomething;
      | --------   |
      | | Link | ----> We want to know about this mouseout
      | |      |   |
      | --------   |
      | --------   |
      | | Link |   |
      | |    ----> | but not about this one
      | --------   |
      --------------
      ---->: mouse movement
      

      另一个显示停止器是,当您将鼠标移入图层,然后移到链接上时,浏览器会在图层上注册一个 mouseout 事件!这对我来说没有多大意义(鼠标仍在图层中),但所有浏览器都同意这一点。

      那么当鼠标实际离开图层时,我们如何拒绝任何未发生的鼠标移出?

      function doSomething(e) {
      if (!e) var e = window.event;
      var tg = (window.event) ? e.srcElement : e.target;
      if (tg.nodeName != 'DIV') return;
      var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
      while (reltg != tg && reltg.nodeName != 'BODY')
          reltg= reltg.parentNode
      if (reltg== tg) return;
      // Mouseout took place when mouse actually left layer
      // Handle event
      }
      

      首先获取事件目标,即。鼠标移出的元素。如果目标不是DIV(图层),则立即结束函数,因为鼠标肯定没有离开图层。

      如果目标是图层,我们仍然不确定鼠标是离开图层还是进入图层内的链接。因此我们要检查事件的relatedTarget/toElement,即。鼠标移动到的元素。

      我们读出这个元素,然后我们将在 DOM 树中向上移动,直到遇到事件的目标(即 DIV)或 body 元素。

      如果我们遇到目标鼠标移向层的子元素,那么鼠标实际上并没有离开层。我们停止函数。

      当函数通过所有这些检查后,我们可以确定鼠标实际上已经离开了层,我们可以采取适当的行动(通常使层不可见)。

      Mouseenter 和 mouseleave

      Microsoft 有另一个解决方案。它创建了两个新事件 mouseenter 和 mouseleave。它们与 mouseover 和 mouseout 几乎相同,只是它们不对事件冒泡做出反应。因此,他们将注册到的整个 HTML 元素视为一个实心块,并且不会对块内发生的鼠标悬停和 -out 做出反应。

      所以使用这些事件也解决了我们的问题:它们只对它们注册到的元素上的鼠标悬停/移出做出反应。

      目前,这些事件仅受 Windows 及更高版本的 Explorer 5.5 支持。也许其他浏览器供应商会复制这些事件。

      所以最好使用 mouseleave 而不是 mouseout,因为它会导致事件冒泡。

      【讨论】:

      • 抱歉,这不是您想要的结果——一旦您尝试在菜单框内移动,它就会消失。
      • 我对您的问题进行了彻底的研究并找到了解决方案。我已经更新了我的答案。检查一下。
      猜你喜欢
      • 2016-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 2013-05-01
      • 1970-01-01
      相关资源
      最近更新 更多