为什么在子元素上执行 mousein 时会触发 mouseout?

问题描述 投票:0回答:2

来自MDN

mouseout事件的定义如下:

当指针设备(通常是鼠标)从附加了侦听器的元素或其子元素之一移开时,将触发 mouseout 事件。

因此,如果我有一个附加了

mouseout
的容器 div,那么我希望当鼠标从其任何子级移出时会触发该事件。但我看到的是,如果鼠标移动到容器的子容器中,即使
mouseout
被触发。这是例子:

x = 0;
$(document).ready(function(){
    $("div.over").mouseout(function(){
        $(".over span").text(x += 1);
    });    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="over" style="background-color:lightgray;padding:20px;width:250px;float:left">
  <h3 style="background-color:white;">Mouseout event triggered: <span></span></h3>
</div>

当鼠标进入

h3
时,
mouseout
上的
div.over
被触发。为什么?

编辑:请提及权威参考文献来支持您的主张。

javascript html jquery mouseevent jquery-events
2个回答
14
投票

由于您的 div 包含子项,因此一旦您“将鼠标悬停在”子项上,您就会“鼠标移出”容器,这是设计使然。因为它位于其自己的可见空间之外,并且位于其子级的可见空间之内。由于子项也在父项内,因此它“继承”事件,因为它被视为单独的体积,但仍在父项的空间内。这就是当您“鼠标移开”孩子时触发该事件的原因。这称为“冒泡”,事件在元素的族树中冒泡。

正如 Mahi 指出的,如果你使用“mouseleave”,它只会在离开附加元素的区域时触发。

MDN 文档在这里解释了其中的差异: https://developer.mozilla.org/en-US/docs/Web/Events/mouseleave

但是权威答案最好看W3C DOM规范:

当指针设备从一个元素移动到其后代元素之一的边界时,必须调度它。

因此它明确指出,当您移动到其子元素之一时,必须触发事件 mouseout。所以发生这种情况的原因是设计、规范造成的:

https://www.w3.org/TR/DOM-Level-3-Events/#event-type-mouseout

我添加了一个示例来显示差异

x = 0;
$(document).ready(function(){
    $("div.over").mouseout(function(e){
        $(".over span").text(x += 1);
        console.log(e.target);
    });    
    $("div.over > h3").mouseover(function(){
        $(".over > h3").css("color", "red");
    }).mouseout(function(){
        $(".over > h3").css("color","black");
    });
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="over" style="background-color:lightgray;padding:20px;width:250px;float:left">
  <h3 style="background-color:white;">Mouseout event triggered: <span></span></h3>
</div>

x = 0;
$(document).ready(function(){
    $("div.over").mouseleave(function(){
        $(".over span").text(x += 1);
    });    
    $("div.over > h3").mouseover(function(){
        $(".over > h3").css("color", "red");
    }).mouseout(function(){
        $(".over > h3").css("color","black");
    });
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="over" style="background-color:lightgray;padding:20px;width:250px;float:left">
  <h3 style="background-color:white;">Mouseout event triggered: <span></span></h3>
</div>

现在,如果您在“z 空间”中向下移动子元素,它不再影响 mouseout 事件:

x = 0;
$(document).ready(function(){
    $("div.over").mouseout(function(){
        $(".over").css("background","red");
    }); 
    $("div.over").mouseover(function(){
        $(".over").css("background","#444");
    });       
    $("div.over > h3").css("display", "block");
    $("div.over > h3").css("position", "relative");
    $("div.over > h3").css("z-index", -1000);
    $("div.over > h3").mouseover(function(){
        $(".over > h3").css("color", "red");
    }).mouseout(function(){
        $(".over > h3").css("color","black");
    });
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="over" style="background-color:lightgray;padding:20px;width:250px;float:left">
  <h3 style="background-color:white;">Mouseout event triggered: <span></span></h3>
</div>


5
投票

当鼠标指针离开任何子元素以及所选元素时,会触发 mouseout 事件。

仅当鼠标指针离开所选元素时才会触发 mouseleave 事件。

© www.soinside.com 2019 - 2024. All rights reserved.