【问题标题】:Why does the mouseout handler behave so illogically in this case?为什么 mouseout 处理程序在这种情况下表现得如此不合逻辑?
【发布时间】:2017-10-21 02:57:25
【问题描述】:

红色方块是具有“父”类的容器的一部分。如果我将鼠标悬停在那个红色方块上,它就会消失。但为什么?我预计它不应该。

预期的行为:它不会消失,因为红色方块是“.parent”容器的一部分,并且我已经明确指出,mouseout 事件发生在该容器上。

有一个建议,这个问题是重复的

JavaScript mouseover/mouseout issue with child element

在某种程度上 - 是的,但我认为这个问题提供了价值,因为它不仅提供了解决方案(“你可以试试这个”),而且还解释了为什么你应该使用它以及为什么初始解决方案不起作用正如它应该的那样。

<span class="parent">Hover mouse over this text<br></span>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
    function removeSquare()
    {
        $(this).find(".kvadrat").remove();
    }

    function addSquare()
    {
        $(this).append("<span style='display:inline-block;width: 50px;height: 50px;background-color:red' class='kvadrat'></span>");
        $(this).on("mouseout", removeSquare);
    }
    $(".parent").on("mouseover", addSquare);
</script>

【问题讨论】:

  • 你已经使用了 $(this).on("mouseout", removeSquare);这就是它消失的原因
  • 但它不应该。 Square 是 $(this) 的一部分。
  • 顺便说一句,您的代码也有另一个问题:每次触发mouseover 事件时,您都在添加mouseout 处理程序的另一个副本。如果您不断将鼠标移入和移出父元素,最终会在其上产生数十个冗余的 mouseout 处理程序。

标签: javascript jquery events dom-events jquery-events


【解决方案1】:

我知道这不是直接回答您的 JavaScript 问题,但如果您不受 JavaScript 限制,我想打开您的眼睛。您可以使用 CSS 轻松实现这一目标。

.kvadrat {
  display: none:

}
.parent:hover > .kvadrat {
  display: inline-block;
  background-color: red;
  width: 50px;height: 50px;
}
<span class="parent">Hover mouse over this text<br>
<span class='kvadrat'></span></span>

【讨论】:

  • 非常感谢您的解决方案!但这并没有取消这个问题,因为我显然不了解 Javascript。
  • 我喜欢你的方法,但有一个问题:如果你将鼠标从文本慢慢悬停到方块上,那么方块就会消失。这就是我过去拒绝这种方法的原因。
  • 如果你的鼠标进入顶部的红色方块,这不会发生,对吧?仅当您尝试从右侧进入正方形时,您基本上停止了将文本悬停。
  • @Thomas:根据您的浏览器及其字体设置,即使从顶部输入也可能会发生也可能不会发生。您几乎可以肯定地通过在 CSS 中添加 .parent { line-height: 2 } 来触发它。解决方法是使.parent 元素成为一个块(使其行之间不能有任何间隙)或在正方形上设置足够的负上边距以确保它始终与文本重叠(可能与实际正方形的可见内容移动到具有相应正上边距的内部元素中)。
  • 没有考虑,但确实可以修复。谢谢!
【解决方案2】:

您可以使用 CSS 实现相同的目的。

.child {
  display: none:
  
}
.parent:hover > .child {
  display: inline-block;
  background-color: red;
  width: 50px;
  height: 50px;
}
<span class="parent">Hover mouse over this text<br>
  <span class='child'></span>
</span>

【讨论】:

  • 最有趣的是:它也有同样的问题:) 将鼠标悬停在 Squares 上后它消失了。
  • 我将鼠标悬停在红色框上,它并没有消失。
  • 慢慢做吧
  • 嗯,我也慢慢试了。我将鼠标悬停在文本和红色框上,什么都没有消失。一旦你移出红框,它就会消失,但当你的鼠标在它上面时它不会消失。
  • 那真的慢点试试:) 浏览器是chrome,如果你把鼠标光标从“Hover”这个词慢慢移到方块上,它会一点点消失
【解决方案3】:

这是.mouseout() 事件的正常行为。

显示触发 mouseout 和 mouseleave 事件的次数。 当指针移出 子元素 时触发 mouseout 好吧,而 mouseleave 仅在指针移出时触发 绑定元素。

您应该使用.mouseenter().mouseleave() 事件,

function removeSquare()
{
$(this).find(".kvadrat").remove();
}

function addSquare()
{
    $(this).append ( "<span style='display:inline-block;width: 50px;height: 50px;background-color:red' class='kvadrat'></span>" );
    
}
$ ( ".parent" ).on ( "mouseenter", addSquare );
$(".parent").on("mouseleave", removeSquare);
.parent {
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="parent">Hover mouse over this text<br></span>

【讨论】:

  • 即使我将鼠标悬停在同一行的正方形右侧(外侧),正方形也不会消失
  • 我玩过 css 看看发生了什么。检查更新的 jsfiddle jsfiddle.net/Lp3L7dp6/3
  • 我没有得到反对票,这是正确的解释。
  • ocanal,这是一个很好的解决方案,但是如果您将鼠标悬停得很慢,您会看到,正方形仍然消失了。
  • @JaroslavTavgen,实际上还有另一个问题,因为您将 inline-blocked 元素放入 inline 元素是无效的。所以你的跨度也必须是内联块。
【解决方案4】:

这是因为事件冒泡。当您进入子跨度时,您的 jQuery 将触发 mouseout,因为您现在已经进入了子跨度。如果你想让它继续运行,请使用 mouseenter 和 louseleave,它在你离开实际元素之前不会触发,无论子元素如何。

<span class="parent">Hover mouse over this text<br></span>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
function removeSquare()
{
$(this).find(".kvadrat").remove();
}

function addSquare()
{
    $(this).append ( "<span style='display:inline-block;width: 50px;height: 50px;background-color:red' class='kvadrat'></span>" );
    $(this).on("mouseleave", removeSquare);
}
$ ( ".parent" ).on ( "mouseenter", addSquare );
</script>

【讨论】:

    【解决方案5】:

    正如其他人所指出的,您最初的问题是 mouseovermouseout 事件也会为子元素触发。该问题的解决方案是使用 jQuery 的 mouseentermouseleave 事件,或者简单地将 JS 代码替换为 CSS :hover pseudo-class

    但是,这里发布的其他 JS 和 CSS 解决方案有时会出现异常行为的原因(如果您将鼠标缓慢移动到方块上会导致方块消失,但如果您快速移动它则不会消失,并且不是在所有浏览器上,即使您慢慢移动)是因为,根据您的浏览器和字体设置,文本的顶行与其下方的正方形之间可能存在也可能不存在小的间隙。如果间隙存在,并且您的鼠标光标在从文本移动到正方形时碰到它,浏览器将认为鼠标已离开父元素,因此将隐藏正方形。

    在父元素上设置(浅蓝色)背景颜色可以清楚地显示问题;根据浏览器选择的字体和行高,父元素和框可能如下所示:

    或者像这样:

    手动设置特别大的行高使问题很容易重现(基于Thomas van Broekhoven's answer的CSS示例):

    .kvadrat {
      display: none;
    }
    .parent:hover > .kvadrat {
      display: inline-block;
      background-color: red;
      width: 50px; height: 50px;
    }
    .parent {
      line-height: 2.0;
      background: lightblue;
    }
    <span class="parent">Hover mouse over this text!<br>
    Here's another line of text.<br>
    <span class='kvadrat'></span></span>

    有两种一般方法可以解决此问题。在可行的情况下,最简单的选择是使父元素成为块,从而消除行之间的间隙。您可能还希望将position: absolute 添加到正方形的样式中,以便它在出现时不会扩展其父元素:

    .kvadrat {
      display: none;
    }
    .parent:hover > .kvadrat {
      display: inline-block;
      position: absolute;
      background-color: red;
      width: 50px; height: 50px;
    }
    .parent {
      display: block;
      line-height: 2.0;
      background: lightblue;
    }
    <span class="parent">Hover mouse over this text!<br>
    Here's another line of text.<br>
    <span class='kvadrat'></span></span>

    或者,如果您真的想坚持使用内联父元素(例如,因为您希望它能够跨越多行文本),您可以在正方形上设置负上边距以确保它与上面的一行文字。如果您不希望正方形与文本可见重叠,您可以进一步将正方形的所有可见内容移动到内部元素中并在其上设置相应的正上边距,如下所示:

    .kvadrat {
      display: none;
    }
    .parent:hover > .kvadrat {
      display: inline-block;
      position: absolute;
      margin-top: -1em;
      border: 1px dashed gray; /* to show the extent of this otherwise invisible element */
    }
    .kvadrat > .inner {
      display: block;
      margin-top: 1em;
      background-color: red;
      width: 50px; height: 50px;
    }
    .parent {
      line-height: 2.0;
      background: lightblue;
    }
    <span class="parent">Hover mouse over this text!<br>
    Here's another line of text.<br>
    <span class='kvadrat'><span class='inner'></span></span></span>

    【讨论】:

    • 感谢您添加这些详细信息。我希望这将有助于其他人理解该理论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多