Detect from which side the mouse left a div
Asked Answered
I

1

6

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?

Imperial answered 3/7, 2017 at 4:52 Comment(10)
Your code seems to work fine...Calender
@Calender Sorry. I mis-linked that best answer's jsFiddle. I had corrected the link to make it link to my jsFiddle.Imperial
Would the previous fiddle's mod work for you?Calender
@Calender Which one?Imperial
The one in jquery from where you have copied.Calender
I think the problem is that it doesn't work with position: absolute. have you tried without that?Yarbrough
@Calender That best answer works for me.Imperial
@IanY. this is interesting to note why javascript is not giving the same answer as jquery.Calender
@JVLobo I deeply apologize for the comment. It seems positioning is affecting the answer. But why?Calender
@IanY. I tested the absolute positioning effect for the best answer as well and the same bug seems to be happening.Calender
Y
14

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!

Yarbrough answered 3/7, 2017 at 11:47 Comment(1)
Thank you very much! This works. Another answer of the other question noticed the issue of absolute positioning, too.Imperial

© 2022 - 2024 — McMap. All rights reserved.