designbuildtest
designbuildtest

Reputation: 23

Mousemove delays firing mouseleave event

Experiencing some strangeness with jQuery mouse events. Check the jsFiddle at: https://jsfiddle.net/Lb8r3907/1/

What I am trying to achieve is an inner element that when the mouse is over it, the pointer element will follow your cursor and when you mouse out of the inner element the pointer is then hidden.

I have an outer element that fills the screen and the mouse enter / leave of this element shows and hides the pointer element that will follow your cursor.

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

What's really odd is that when the mousemove event is activated it seems to delay the firing of the mouseleave event.

I also notice that the delay really only seems to occurr when you mouse out on the right or bottom edge of the inner element.

Can anyone offer any insights as to why this is occurring?? I would really like to know how to address this issue or if it is a bug in the browser / jQuery.

Upvotes: 2

Views: 1269

Answers (3)

Angus
Angus

Reputation: 1

You can add CSS pointer-events:none; to .pointer. pointer-events is supported in all major browsers

This CSS property, when set to "none" allows elements to not receive hover/click events, instead the event will occur on anything behind it.

https://caniuse.com/pointer-events

Upvotes: 0

Georgios Dimitriadis
Georgios Dimitriadis

Reputation: 685

I would have tackled this problem differently. Instead, I would use the boundary box of the .inner and add the .pointer if the cursor was inside. This way you only need one mouse listener and the code is easier to understand (in my opinon):

html:

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

CSS (no change)

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

Upvotes: 0

Barath Ravikumar
Barath Ravikumar

Reputation: 5836

Your "Pointer" is consuming some of the events intended for the "outer" element. Try some spacing between the cursor and the pointer. The space should help keep the pointer away when you mouse out to the outer, so that the outer gets its events as intended

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

This change Should work better.

Upvotes: 1

Related Questions