Reputation: 14530
I have these two on mouseover and mouseout events in JS. They are for checking wether I'm hovering over a panel on my page. But the problem is when I hover over a panel it triggers (good), but then when I hover over another element inside that panel it triggers a the mouseout event and then the mouseover events again when I move to another part inside the panel.
I only want the mouseover and mouseout events firing once! Once for entering the panel another for leaving it. Is there a way to propagate the on mouseover call to all child elements in the div.panel. It seems like that would correct it.
Here are my events
$(document).off("mouseover").on("mouseover", "div.panel", function() {
var panelSpaceId = $(this).attr("data-spaceId");
var marker = _.find(scope.markers, function(item) {
return item.spaceId == panelSpaceId
})
google.maps.event.trigger(marker, "mouseover");
console.log("over" + marker.spaceId);
});
$(document).off("mouseout").on("mouseout", "div.panel", function() {
var panelSpaceId = $(this).attr("data-spaceId");
var marker = _.find(scope.markers, function(item) {
return item.spaceId == panelSpaceId
})
google.maps.event.trigger(marker, "mouseout");
console.log("out" + marker.spaceId);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 29
Views: 23702
Reputation: 66103
You can avoid this issue by using mouseenter
instead of mouseover
, and mouseleave
instead of mouseout
. The reason is simple: mouseenter
is only fired when the cursor "enters" the element, which includes its children—so hovering over the child of the element does not re-fire the mouseenter
event.
This similar logic applies to mouseleave
vs of mouseout
. You can see this effect happening based on a fiddle created by @gilly3 in his answer to a similar question. I am not marking your question as duplicate because your answer is primarily troubleshooting mouseover/leave
events instead of asking about the distinct between mouseover/enter
and mouseout/leave
.
It is helpful to imagine this:
Here is your modified code, where I simply replaced the offending events with the right ones:
$(document).off("mouseenter").on("mouseenter", "div.panel", function() {
var panelSpaceId = $(this).attr("data-spaceId");
var marker = _.find(scope.markers, function(item) {
return item.spaceId == panelSpaceId
})
google.maps.event.trigger(marker, "mouseenter");
console.log("over" + marker.spaceId);
});
$(document).off("mouseleave").on("mouseleave", "div.panel", function() {
var panelSpaceId = $(this).attr("data-spaceId");
var marker = _.find(scope.markers, function(item) {
return item.spaceId == panelSpaceId
})
google.maps.event.trigger(marker, "mouseleave");
console.log("out" + marker.spaceId);
});
Upvotes: 72