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=".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>
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./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.
Share Improve this question edited Jul 25, 2021 at 13:24 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Nov 29, 2016 at 10:32 user31782user31782 7,58716 gold badges78 silver badges157 bronze badges 11- 3 Because mouse pointer getting out from current element. Use mouseleave instead. It will triggered when pointer leave from releated element bounding box – Tolgahan Albayrak Commented Nov 29, 2016 at 10:34
-
@TolgahanAlbayrak No the mouse is not getting out from the current element. The
h3
is insidediv.outer
. – user31782 Commented Nov 29, 2016 at 10:39 - @user31782 :) Imagine that you have a plate just front of your head. And some housefly landed on your shoulder. When it landed, you say there is a housefly on your body. Let's say that housefly jumped on that plate. You are not able to see that. So, what you say about housefly ? It is still on you ? – Tolgahan Albayrak Commented Nov 29, 2016 at 10:54
- 1 @TolgahanAlbayrak but that's not MDN definition says – Mahi Commented Nov 29, 2016 at 11:03
- 1 @TolgahanAlbayrak if you are in your home and you enter into your room . will that mean you are out of home ? – Mahi Commented Nov 29, 2016 at 11:40
2 Answers
Reset to default 14Since your div contains children, you "mouseout" of the container once you "mouseover" the children, this is by design. Since it is outside of its own visible space, and inside of its 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/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 its child elements. So the reason for why this happens is by design, by specification:
https://www.w3/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./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./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./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>
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.