Simple mouse movement event:
Enter
mouseenter: No bubbles
mouseover: Bubble
The mouseover event will be triggered regardless of whether the mouse pointer passes through the selected element or its child element.
The mouseenter event will only be triggered when the mouse pointer passes through the selected element.
Move out
mouseleave: No bubbles
mouseout: Bubble
The mouseout event will be triggered regardless of whether the mouse pointer leaves the selected element or any child element.
The mouseleave event will only be triggered when the mouse pointer leaves the selected element.
Let’s observe the problem through a case study:
Binding mouseout events to a nested hierarchy will find that mouseout events are different from those imagined.
<!DOCTYPE html><div class="out overout" style="width:40%;height:120px; margin:0 15px;background-color:#D6EDFC;float:left;" data-mce-style="width:40%; height:120px; margin: 0 15px; background-color: #d6edfc; float: left;"><p style="border:1px solid red" data-mce-style="border:1px solid red;">External child element</p><div class="in overout" style="width:60%;background-color:#FFCC00;margin:10px auto;" data-mce-style="width:60%; background-color: #ffcc00; margin: 10px auto;"><p style="border:1px solid red" data-mce-style="border:1px solid red;">Internal child elements</p><p >0</p>
</div><p >0</p>
</div><script type="text/javascript">
var i = 0;
var k = 0;
('.out')[0].addEventListener('mouseout',function(e){
("#inshow")[0].textContent = (++i)
();
},false)
('.in')[0].addEventListener('mouseout',function(){
("#outshow")[0].textContent = (++k)
},false)
</script>
We found a problem with mouseout event:
1. Cannot stop bubbles
2. It will also trigger on the internal child elements
The same problem also has the mouseover event. So how do we stop bubbling when the stopPropagation method fails?
1. In order to prevent the repeated triggering of mouseover and mouseout, we need to use an attribute relatedTarget of the event object. This property is used to judge the attributes of the related nodes of the mouseover and mouseout event target node. Simply put, when the mouseover event is triggered, the relatedTarget attribute represents the node that the mouse has just left, and when the mouseout event is triggered, it represents the object that the mouse moves to. Since MSIE does not support this property, it has substituted properties, namely fromElement and toElement.
2. With this attribute, we can clearly know which object our mouse is moving from and where it is moving. In this way, we can determine whether the associated object is inside the object where we are going to trigger the event, or whether it is the object itself. Through this judgment, we can reasonably choose whether the event is really going to be triggered.
3. Here we also use a method to check whether an object is contained in another object, the contains method. MSIE and FireFox provide methods for checking respectively, and a function is encapsulated here.
jQuery's processing is the same
({
mouseenter: "mouseover",
mouseleave: "mouseout",
pointerenter: "pointerover",
pointerleave: "pointerout"
}, function(orig, fix) {
[orig] = {
delegateType: fix,
bindType: fix,
handle: function(event) {
var ret,
target = this,
related = ,
handleObj = ;
// For mousenter/leave call the handler if related is outside the target.
// NB: No relatedTarget if the mouse left/entered the browser window
if (!related || (related !== target && !(target, related))) {
= ;
ret = (this, arguments);
= fix;
}
return ret;
}
};
});