Search code examples
javascriptjquerymousemovemouseentermouseleave

How to enable/disable the mousemove function when entering leaving a contained element (using mouseenter & mouseleave)


So right now I'm currently making a mousemove funtion that has a div following my cursor as I move around the screen. I want to keep that element within the "header" block so right now I just have it disappear with css and a mouseleave function whenever my cursor leaves the header element.

What I want to do, is as I leave the header element, the positioning of the div to reset into its original place from page load. Here's a snippet of my js edited for clarity:

$( ".homehero" ).mouseleave(function() {
    // Not sure how to change this function here to turn off:
    /* $(document).mousemove(function(e) {
           $('.case-study #scene').offset({
               left: e.pageX + 70,
               top: e.pageY + 70
           });
        });  */
    $( "#scene" ).addClass( "hide-hero" ); // currently just hiding it 
});
$( ".homehero" ).mouseenter(function() {
    $(document).mousemove(function(e) {
        $('.case-study #scene').offset({
            left: e.pageX + 70,
            top: e.pageY + 70
        });
    });
    $( "#scene" ).removeClass( "hide-hero" ); // currently just showing it again on mouseenter
});

Note, #scene is the div that is inside of the header .homehero element. Below is a screencapture of what I'm currently doing now.

Screen capture of mousemove

Appreciate any insights!


Solution

  • While you could use jQuery's off() method which lets you actually remove the listener you would need to keep a reference to that function in order for off() to remove just that listener. Otherwise you would have to call .off("mousemove"). When called without a function reference it will remove all listeners. This could cause problems if some other code needs to add the same event.

    Instead you can setup the mousemove like the others. And then use a flag that you set in mouseenter and unset in mouseleave. Test for that flag in your mousemove callback, leaving immediately if it tests as false

    var enableMove = false;
    
    $(document).mousemove(function(e) {
      if(!enableMove) return;
    
      $('.case-study #scene').offset({
        left: e.pageX + 70,
        top: e.pageY + 70
      });
    });
    
    $( ".homehero" ).mouseleave(function() {
      enableMove = false;
      $( "#scene" ).addClass( "hide-hero" );
    });
    
    $( ".homehero" ).mouseenter(function() {
      enableMove = false;
      $( "#scene" ).removeClass( "hide-hero" ); 
    });
    

    As for the positioning issue you could just save the element's coordinates on mouseenter and use that saved data to set the coordinates on exit. You can use jQuery's data() method to save the information on the element itself and retrieve it later.

    //in mouseenter
    var $element = $('.case-study #scene');
    $element.data("originalCoordinates",$element.offset());
    
    //in mouseleave
    var $element = $('.case-study #scene');
    $element.offset( $element.data("originalCoordinates") );