I am trying to create a map, and a certain position of this map should highlight when i hover the mouse over a button. When the mouse enters the overlay image is displayed as it should be but when the mouse moves, inside the hover button, the overlay image is flashing and the mouseEnter and mouseLeave events are triggered repeatedly. I also tried with mouseOver, hover and mouseout with the same result. Am I doing something wrong?
HTML:
<div id="map">
<img src="images/map/map.png" />
<img src="images/map/mapHover.png" id="hoverhighlands" class="hoverButton"/>
<img src="images/map/mapHover.png" id="hovernorth" class="hoverButton"/>
<img src="images/map/mapHover.png" id="hovercentral" class="hoverButton"/>
<img src="images/map/mapHover.png" id="hoverlothian"class="hoverButton" /> <img src="images/map/mapHover.png" id="hoverwest" class="hoverButton" />
<img src="images/map/central.png" class="mapOverlay" id="central" />
<img src="images/map/highlands.png" class="mapOverlay" id="highlands" />
<img src="images/map/lothian.png" class="mapOverlay" id="lothian" />
<img src="images/map/northeast.png" class="mapOverlay" id="north"/>
<img src="images/map/west.png" class="mapOverlay" id="west"/>
</div>
JS:
function setMapOverlays() {
$(".mapOverlay").hide();
$(".hoverButton").mouseenter(
function () {
var id = $(this).attr('id');
id = id.substr(5);
showOverlay(id);
}).mouseleave(function () {
console.log('mouseleave');
var id = $(this).attr('id');
id = id.substr(5);
hideOverlay(id);
})
}
function showOverlay(id) {
$('#' + id).show();
}
function hideOverlay(id) {
$('#' + id).hide();
}
EDIT
Ok, I got why it's not working. When the .show() function triggers my overlay images are placed on top of the hoverButtons, triggering the onmouseleave.
I managed to verify that placing a z-index:2 on hoverButton and z-index:1 on mapOverlay. This way the event is not fired when I move the mouse.
So I have a temporary fix. Moving the onmouseleave event to my mapOverlays instead of my hoverButtons did the trick. function setMapOverlays() { $(".mapOverlay").hide(); $(".hoverButton").mouseenter( function () { console.log('enter'); var id = $(this).attr('id'); id = id.substr(5);
showOverlay(id);
});
$('.mapOverlay').mouseleave(function () {
console.log('mouseleave');
hideOverlay($(this));
})
}
This works BUT it's not the desired behavior. I want the Overlay to hide when my mouse moves out of the hoverButton. Any suggestions on how to do that?
Two images to help explain exactly what I'm doing:
I am trying to create a map, and a certain position of this map should highlight when i hover the mouse over a button. When the mouse enters the overlay image is displayed as it should be but when the mouse moves, inside the hover button, the overlay image is flashing and the mouseEnter and mouseLeave events are triggered repeatedly. I also tried with mouseOver, hover and mouseout with the same result. Am I doing something wrong?
HTML:
<div id="map">
<img src="images/map/map.png" />
<img src="images/map/mapHover.png" id="hoverhighlands" class="hoverButton"/>
<img src="images/map/mapHover.png" id="hovernorth" class="hoverButton"/>
<img src="images/map/mapHover.png" id="hovercentral" class="hoverButton"/>
<img src="images/map/mapHover.png" id="hoverlothian"class="hoverButton" /> <img src="images/map/mapHover.png" id="hoverwest" class="hoverButton" />
<img src="images/map/central.png" class="mapOverlay" id="central" />
<img src="images/map/highlands.png" class="mapOverlay" id="highlands" />
<img src="images/map/lothian.png" class="mapOverlay" id="lothian" />
<img src="images/map/northeast.png" class="mapOverlay" id="north"/>
<img src="images/map/west.png" class="mapOverlay" id="west"/>
</div>
JS:
function setMapOverlays() {
$(".mapOverlay").hide();
$(".hoverButton").mouseenter(
function () {
var id = $(this).attr('id');
id = id.substr(5);
showOverlay(id);
}).mouseleave(function () {
console.log('mouseleave');
var id = $(this).attr('id');
id = id.substr(5);
hideOverlay(id);
})
}
function showOverlay(id) {
$('#' + id).show();
}
function hideOverlay(id) {
$('#' + id).hide();
}
EDIT
Ok, I got why it's not working. When the .show() function triggers my overlay images are placed on top of the hoverButtons, triggering the onmouseleave.
I managed to verify that placing a z-index:2 on hoverButton and z-index:1 on mapOverlay. This way the event is not fired when I move the mouse.
So I have a temporary fix. Moving the onmouseleave event to my mapOverlays instead of my hoverButtons did the trick. function setMapOverlays() { $(".mapOverlay").hide(); $(".hoverButton").mouseenter( function () { console.log('enter'); var id = $(this).attr('id'); id = id.substr(5);
showOverlay(id);
});
$('.mapOverlay').mouseleave(function () {
console.log('mouseleave');
hideOverlay($(this));
})
}
This works BUT it's not the desired behavior. I want the Overlay to hide when my mouse moves out of the hoverButton. Any suggestions on how to do that?
Two images to help explain exactly what I'm doing:
Share Improve this question edited Oct 15, 2012 at 11:45 caiocpricci2 asked Oct 15, 2012 at 11:11 caiocpricci2caiocpricci2 7,80810 gold badges57 silver badges88 bronze badges 3-
Try putting a semi-colon after the
mouseleave
function.hideOverlay(id); });
– keyboardP Commented Oct 15, 2012 at 11:17 - Thanks but it didn't help. I guess I'm doing something wrong with the overlays. Maybe when I show the image over the hover button it triggers the mouse leave because the button was overlayed by the image? – caiocpricci2 Commented Oct 15, 2012 at 11:36
- Semicolons are not required in javascript unless the proceeding line starts with a [ or a ( – Rick Kukiela Commented Sep 17, 2018 at 20:56
2 Answers
Reset to default 3Don't use mouseleave event for hoverButton class. Try instead handle mousemove event in overlay when it shown and check is mous still over element that initiated overlay show method.
function setMapOverlays() {
$(".mapOverlay").hide();
$(".hoverButton").mouseenter(function() {
var id = $(this).attr('id');
id = id.substr(5);
showOverlay(id, this);
});
};
function showOverlay(id, initiator) {
initiator = $(initiator);
initiatorBoundary = {
x1: initiator.offset().left,
x2: initiator.offset().left + initiator.outerWidth(),
y1: initiator.offset().top,
y2: initiator.offset().top + initiator.outerHeight()
};
$('#' + id).mousemove(function(event) {
if (event.pageX < initiatorBoundary.x1 || event.pageX > initiatorBoundary.x2 || event.pageY < initiatorBoundary.y1 || event.pageY > initiatorBoundary.y2) {
$(this).hide();
}
}).show();
}
jsFiddle here
BTW, maybe it's would be easier implement without overlay element. Did you consider to change whole map image on mouseenter and mouseleave?
I fix your js code and add an data-id attribute to img tags
new html is:
<div id="map">
<img src="images/map/map.png" />
<img src="images/map/mapHover.png" id="hoverhighlands" class="hoverButton" data-id="highlands" />
<img src="images/map/mapHover.png" id="hovernorth" class="hoverButton" data-id="north" />
<img src="images/map/mapHover.png" id="hovercentral" class="hoverButton" data-id="central" />
<img src="images/map/mapHover.png" id="hoverlothian"class="hoverButton" data-id="lothian" />
<img src="images/map/mapHover.png" id="hoverwest" class="hoverButton" data-id="west" />
<img src="images/map/central.png" class="mapOverlay" id="central" data-id="central" />
<img src="images/map/highlands.png" class="mapOverlay" id="highlands" data-id="highlands" />
<img src="images/map/lothian.png" class="mapOverlay" id="lothian" data-id="lothian" />
<img src="images/map/northeast.png" class="mapOverlay" id="north" data-id="north" />
<img src="images/map/west.png" class="mapOverlay" id="west" data-id="west" />
</div>
new jscode is:
function setMapOverlays() {
$(".mapOverlay").hide();
function showOverlay(id) {
$('#' + id).show();
}
function hideOverlay(id) {
$('#' + id).hide();
}
function hover() {
console.log('hover', this, arguments);
var id = $(this).data('id');
showOverlay(id);
}
function leave(evt) {
console.log('leave', this, arguments);
var id = $(this).data('id');
var hovered = evt.relatedTarget;
if ($(hovered).data('id') == id) {
$(hovered).mouseleave(leave);
return;
}
hideOverlay(id);
}
$(".hoverButton")
.mouseenter(hover)
.mouseleave(leave);
}
you can try this on jsFiddle