Search code examples
javascriptdirectionmouseleave

Detect from which side the mouse left a div


I modified the code of the best answer of another question (which aimed to detect from which side the mouse entered a div) in order to make it detect from which side the mouse left a div.

Here is the my code. I changed the log to display in the console. But somehow the results are always being "right" or "bottom" and no "top" or "left".

Any advise, please?


Solution

  • I've been working a bit on the code and I've modified some stuff.

    Since you're positioning your div with absolute position, you need to check the position on a different way.

    First, I'm using getBoundingClientRect() which returns the position of the element (left, top, right and bottom).

    Then I get the mouse coordinates and I calculate from which edge is closest.

    You can see an example of my code here:

    document.querySelector('#content').onmouseleave = function(mouse) {
      var edge = closestEdge(mouse, this);
      console.log(edge);
    }
    
    function closestEdge(mouse, elem) {
      var elemBounding = elem.getBoundingClientRect();
    
      var elementLeftEdge = elemBounding.left;
      var elementTopEdge = elemBounding.top;
      var elementRightEdge = elemBounding.right;
      var elementBottomEdge = elemBounding.bottom;
    
      var mouseX = mouse.pageX;
      var mouseY = mouse.pageY;
    
      var topEdgeDist = Math.abs(elementTopEdge - mouseY);
      var bottomEdgeDist = Math.abs(elementBottomEdge - mouseY);
      var leftEdgeDist = Math.abs(elementLeftEdge - mouseX);
      var rightEdgeDist = Math.abs(elementRightEdge - mouseX);
    
      var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist);
    
      switch (min) {
        case leftEdgeDist:
          return "left";
        case rightEdgeDist:
          return "right";
        case topEdgeDist:
          return "top";
        case bottomEdgeDist:
          return "bottom";
      }
    }
    #content {
      width: 100px;
      height: 100px;
      background: lightblue;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    <div id="content"></div>

    I hope that helps you.

    Cheers!