Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is mouseout fired when mousein is performed on a child element?

The definition of mouseout event from MDN is as:

The mouseout event is fired when a pointing device (usually a mouse) is moved off the element that has the listener attached or off one of its children.

So if I have a container div to whom mouseout is attached then I expect the event to be fired if the mouse moves out from any of its children. But what I am seeing is if mouse is moved in to container's child even then mouseout is being fired. Here is the example:

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>

When the mouse is entered into the h3 the mouseout on div.over is triggered. Why?

Edit: Please mention authoritative reference to back up your claim.

like image 374
user31782 Avatar asked Nov 29 '16 10:11

user31782


People also ask

Is the Mouseout event fired?

The mouseout event is fired at an Element when a pointing device (usually a mouse) is used to move the cursor so that it is no longer contained within the element or one of its children.

Which event is fired when the mouse pointer is moved out of an element?

The mouseleave event is fired at an Element when the cursor of a pointing device (usually a mouse) is moved out of it.

What is the difference between mouseover and Mouseenter?

The mouseover event triggers when the mouse pointer enters the div element, and its child elements. The mouseenter event is only triggered when the mouse pointer enters the div element. The onmousemove event triggers every time the mouse pointer is moved over the div element.


2 Answers

Since your div contains children, you "mouseout" of the container once you "mouseover" the children, this is by design. Since it is outside of it's own visible space, and inside of it's child's visible space. Since the child is also within the parent, it "inherits" the event, as it is treated as a separate volume, but still inside the space of the parent. This is why the event is triggered when you "mouseout" of the child. This is called "bubbling" the event bubbles up the family tree of elements.

As Mahi pointed out, if you use "mouseleave" it will only trigger once it leaves the area of the attached element.

The MDN documentation explain the difference here: https://developer.mozilla.org/en-US/docs/Web/Events/mouseleave

But the authoritative answer is best viewed in the W3C DOM specification:

it MUST be dispatched when the pointer device moves from an element onto the boundaries of one of its descendent elements.

So it clearly states that the event mouseout MUST be triggered when you move ONTO one of the child elements. So the reason for why this happens is by design, by specification:

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

I have added a sample to show the difference

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>

Now if you move the child element down in "z-space" it no longer effects the mouseout event:

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>
like image 164
Espen Avatar answered Sep 19 '22 00:09

Espen


The mouseout event triggers when the mouse pointer leaves any child elements as well the selected element.

The mouseleave event is only triggered when the mouse pointer leaves the selected element.

like image 24
Mahi Avatar answered Sep 21 '22 00:09

Mahi