为什么mouseout处理程序在这种情况下表现得如此不合逻辑?

Jar*_*gen 7 javascript jquery events dom-events jquery-events

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

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

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

带有子元素的JavaScript mouseover/mouseout问题

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

<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>
Run Code Online (Sandbox Code Playgroud)

oca*_*nal 11

这是.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);
Run Code Online (Sandbox Code Playgroud)
.parent {
  display: inline-block;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Ilm*_*nen 6

正如其他人所指出的那样,你最初的问题是,mouseover并且mouseout事件也会触发子元素.该问题的解决方案是使用jQuery mouseentermouseleave事件,或者只是用CSS :hover伪类替换JS代码.

然而,其他JS和CSS解决方案在这里发布的原因有时会表现得不规律(如果你慢慢地将鼠标移到它上面会导致方块消失,但如果你快速移动它就不会消失,而不是在所有浏览器上,即使你慢慢地移动它)是因为,根据您的浏览器和字体设置,文本的顶行与其下方的正方形之间可能存在或可能没有小差距.如果存在间隙,并且鼠标光标在从文本移动到正方形时触及它,则浏览器将认为鼠标已离开父元素,因此将隐藏正方形.

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

截图(小线高,线之间没有间隙)

或者像这样:

截图(大线高度与线之间的间隙)

手动设置特别大的线高使问题容易再现(CSS示例基于Thomas van Broekhoven的回答):

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

有两种解决此问题的常规方法.在可行的情况下,最简单的选择是使父元素成为块,从而消除线之间的间隙.您可能还希望添加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;
}
Run Code Online (Sandbox Code Playgroud)
<span class="parent">Hover mouse over this text!<br>
Here's another line of text.<br>
<span class='kvadrat'></span></span>
Run Code Online (Sandbox Code Playgroud)

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

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Tho*_*ven 5

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

.kvadrat {
  display: none:

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