为什么 mouseout 处理程序在这种情况下表现得如此不合逻辑?
Why does the mouseout handler behave so illogically in this case?
红色方块是class"parent"容器的一部分。如果我将鼠标悬停在那个红色方块上,它就会消失。但为什么?我预计它不应该。
预期行为:它不会消失,因为红色方块是“.parent”容器的一部分,而且我已经明确说明,mouseout 事件发生在该容器上。
有人建议,这个问题与
重复
JavaScript mouseover/mouseout issue with child element
在某种程度上 - 是的,但我认为这个问题提供了价值,因为它不仅提供了解决方案("you can try this"),而且还解释了为什么你应该使用它以及为什么初始解决方案不是正常工作。
<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>
我知道这不是直接回答你的 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>
您可以使用 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>
这是 .mouseout() 事件的正常行为。
Show the number of times mouseout and mouseleave events are triggered.
mouseout fires when the pointer moves out of the child element as
well, while mouseleave fires only when the pointer moves out of the
bound element.
你应该使用 .mouseenter() and .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>
是因为事件冒泡。当您进入子跨度时,您 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>
正如其他人所指出的,您最初的问题是 mouseover
和 mouseout
事件也会为子元素触发。该问题的解决方案是使用 jQuery 的 mouseenter
and mouseleave
events, or simply to replace the JS code with the CSS :hover
pseudo-class.
然而,这里发布的其他JS和CSS解决方案的原因有时会表现不稳定(如果您将鼠标缓慢移动到正方形上,则方形消失,但如果快速移动则不会消失,而不是在所有浏览器上,即使你移动它很慢)是因为,根据你的浏览器和字体设置,文本的顶行和它下面的方块之间可能有也可能没有小间隙。如果间隙存在,当你的鼠标光标从文本移动到正方形时碰到它,浏览器会认为鼠标已经离开父元素,从而隐藏正方形。
在父元素上设置(浅蓝色)背景颜色可以清楚地显示问题;根据浏览器选择的字体和行高,父元素和框可能如下所示:
或者像这样:
手动设置特别大的行高会使问题很容易重现(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>
红色方块是class"parent"容器的一部分。如果我将鼠标悬停在那个红色方块上,它就会消失。但为什么?我预计它不应该。
预期行为:它不会消失,因为红色方块是“.parent”容器的一部分,而且我已经明确说明,mouseout 事件发生在该容器上。
有人建议,这个问题与
重复JavaScript mouseover/mouseout issue with child element
在某种程度上 - 是的,但我认为这个问题提供了价值,因为它不仅提供了解决方案("you can try this"),而且还解释了为什么你应该使用它以及为什么初始解决方案不是正常工作。
<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>
我知道这不是直接回答你的 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>
您可以使用 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>
这是 .mouseout() 事件的正常行为。
Show the number of times mouseout and mouseleave events are triggered. mouseout fires when the pointer moves out of the child element as well, while mouseleave fires only when the pointer moves out of the bound element.
你应该使用 .mouseenter() and .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>
是因为事件冒泡。当您进入子跨度时,您 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>
正如其他人所指出的,您最初的问题是 mouseover
和 mouseout
事件也会为子元素触发。该问题的解决方案是使用 jQuery 的 mouseenter
and mouseleave
events, or simply to replace the JS code with the CSS :hover
pseudo-class.
然而,这里发布的其他JS和CSS解决方案的原因有时会表现不稳定(如果您将鼠标缓慢移动到正方形上,则方形消失,但如果快速移动则不会消失,而不是在所有浏览器上,即使你移动它很慢)是因为,根据你的浏览器和字体设置,文本的顶行和它下面的方块之间可能有也可能没有小间隙。如果间隙存在,当你的鼠标光标从文本移动到正方形时碰到它,浏览器会认为鼠标已经离开父元素,从而隐藏正方形。
在父元素上设置(浅蓝色)背景颜色可以清楚地显示问题;根据浏览器选择的字体和行高,父元素和框可能如下所示:
或者像这样:
手动设置特别大的行高会使问题很容易重现(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>