Mousemove 延迟触发 mouseleave 事件

Mousemove delays firing mouseleave event

jQuery 鼠标事件有些奇怪。 检查 jsFiddle:https://jsfiddle.net/Lb8r3907/1/

我想要实现的是一个内部元素,当鼠标悬停在它上面时,指针元素将跟随您的光标,当您将鼠标移出内部元素时,指针就会隐藏。

我有一个填满屏幕的外部元素,鼠标进入/离开此元素会显示和隐藏将跟随您的光标的指针元素。

$(function() {
  $('.outer').on('mouseenter', function(){
    console.log('MOUSE OVER OUTER!!');
    if($('.pointer').is(':visible')){
      $('.pointer').fadeOut(50);
    }
  });
  //
  $('.outer').on('mouseleave', function(){
    console.log('MOUSE OUT OF OUTER!!!');
    if(!$('.pointer').is(':visible')){
      $('.pointer').fadeIn(50);
    }
  });
  //
  $('.inner').on('mousemove', function(e){
    var mX = e.pageX-$('.inner').offset().left,
    mY = e.pageY-$('.inner').offset().top;
    $('.pointer').css({"top": mY+"px", "left": mX+"px"});
  });
});
.outer { position:absolute; display:block; z-index:0; top:0px; left:0px; width:100%; height:100%; background-color:rgba(255,0,0,0.5); }
.inner { position:absolute; display:block; z-index:1; top:50%; left:50%; width:50%; height:25%; margin-top:-12.5%; margin-left:-25%; background-color:#fff; }
.inner .pointer { display:block; position:absolute; top:50%; left:50%; width:50px; height:50px; background-color:blue; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<body>
  <div class="outer"></div>
  <div class="inner">
    <div class="pointer" style="display:none;"></div>
  </div>
</body>

真正奇怪的是,当 mousemove 事件被激活时,它似乎延迟了 mouseleave 事件的触发。

我还注意到,延迟似乎只发生在您将鼠标移到内部元素的右侧或底部边缘时。

任何人都可以提供任何关于为什么会发生这种情况的见解吗? 我真的很想知道如何解决这个问题,或者它是否是浏览器中的错误/jQuery。

您的 "Pointer" 正在消耗一些用于 "outer" 元素的事件。 尝试在光标和指针之间留出一些间距。当您将鼠标移到外部时,space 应该有助于使指针远离,以便外部按预期获得其事件

$('.pointer').css({"top": mY+2+"px", "left": mX+2+"px"});

这个变化 Should work 更好。

我会以不同的方式解决这个问题。相反,如果光标在里面,我会使用 .inner 的边界框并添加 .pointer。这样你只需要一个鼠标侦听器并且代码更容易理解(我认为):

html:

<div class="container">
    <div class="outer"></div>
    <div class="inner">
        <div class="pointer" style="display:none;"></div>
    </div>
</div>

CSS(无变化)

JS:

$(function() {
    var rect = $('.inner')[0].getBoundingClientRect();
    $('.container').on('mousemove', function(e) {
        var mX = e.pageX;
        var mY = e.pageY;
        // Is the cursor inside the boundaries?
        if(mX > rect.x && mX < rect.x + rect.width && mY > rect.y && mY < rect.y + rect.height ) {
            if(!$('.pointer').is(':visible')) {  // This can be optimized as well
                $('.pointer').show();
            }
            $('.pointer').css({"top": mY - rect.y, "left": mX - rect.x});
        } else {
            $('.pointer').hide(); // This can be optimized as well
        }
    });
});