最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why mouseleave is triggering all the time? - Stack Overflow

programmeradmin1浏览0评论

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
Add a ment  | 

2 Answers 2

Reset to default 3

Don'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

发布评论

评论列表(0)

  1. 暂无评论