为啥mouseleave一直在触发?

Posted

技术标签:

【中文标题】为啥mouseleave一直在触发?【英文标题】:Why mouseleave is triggering all the time?为什么mouseleave一直在触发? 【发布时间】:2012-10-05 08:28:45 【问题描述】:

我正在尝试创建地图,当我将鼠标悬停在按钮上时,该地图的某个位置应突出显示。当鼠标进入时,覆盖图像会按原样显示,但是当鼠标移动时,在悬停按钮内,覆盖图像会闪烁,并且会重复触发 mouseEnter 和 mouseLeave 事件。我还尝试了 mouseOver、hover 和 mouseout,结果相同。我做错了吗?

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();

编辑

好的,我知道为什么它不起作用了。当 .show() 函数触发时,我的叠加图像被放置在 hoverButtons 的顶部,触发 onmouseleave。

我设法验证了在 hoverButton 上放置 z-index:2 并在 mapOverlay 上放置 z-index:1。这样当我移动鼠标时不会触发事件。

所以我有一个临时修复。将 onmouseleave 事件移动到我的 mapOverlays 而不是我的 hoverButtons 就可以了。 函数 setMapOverlays() $(".mapOverlay").hide(); $(".hoverButton").mouseenter( 功能 () console.log('进入'); var id = $(this).attr('id'); id = id.substr(5);

            showOverlay(id);
        );

    $('.mapOverlay').mouseleave(function () 
        console.log('mouseleave');               
        hideOverlay($(this));
    )

这可行,但它不是所需的行为。当我的鼠标移出悬停按钮时,我希望覆盖隐藏。关于如何做到这一点的任何建议?

两张图片可以帮助解释我在做什么:

【问题讨论】:

尝试在mouseleave 函数后加一个分号。 hideOverlay(id); ); 谢谢,但没有帮助。我想我在叠加层上做错了。也许当我在悬停按钮上显示图像时,它会触发鼠标离开,因为按钮被图像覆盖? javascript 中不需要分号,除非前面的行以 [ 或 ( 【参考方案1】:

不要对 hoverButton 类使用 mouseleave 事件。尝试在显示时处理覆盖中的 mousemove 事件,并检查鼠标是否仍在启动覆盖显示方法的元素上方。

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

顺便说一句,也许没有覆盖元素会更容易实现。您是否考虑过在 mouseenter 和 mouseleave 上更改整个地图图像?

【讨论】:

此解决方案完美运行。我考虑过这样做,但我认为更换整个地图并不能解决我的问题。蓝色按钮将覆盖文本(高地和高地),如果我将背景图像设置在顶部,我会回到最初的问题!再次感谢! 不客气。关于整个地图图像操作:您可以仅在地图图像上绘制标记并将透明的悬停按钮放置在适当的位置 我认为现在这只是额外的不必要的工作。您的解决方案在每个浏览器中都能正常工作!但是下次我会记住它,或者以防万一我们遇到问题! :)【参考方案2】:

我修复了你的 js 代码并为 img 标签添加了一个 data-id 属性

新的 html 是:

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

新的jscode是:

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);

你可以在jsFiddle试试这个

【讨论】:

这个解决方案几乎可以工作。问题在于,叠加图像中有透明背景。请注意,深蓝色从左到右拍摄整个图像。那边是透明的背景。要触发隐藏,我必须将鼠标一直移出背景。但是非常感谢您的回复。我是 javascript 的初学者,很高兴看到解决问题的不同方法!

以上是关于为啥mouseleave一直在触发?的主要内容,如果未能解决你的问题,请参考以下文章

触摸板上的Chrome点击会触发mouseleave

在 Angular 中拖动时触发 mouseenter 和 mouseleave

mouseover mouseleave

mouseover,mouseenter,mouseout,mouseleave的区别

mouseover与mouseenter,mouseout与mouseleave的区别

jQuery mouseover与mouseenter,mouseout与mouseleave的区别