Patrick Patrick - 5 months ago 27
jQuery Question

jQuery: Any chance to detect from which side the mouse entered a div without the "Offset" Method?

Is there a way to detect from which side of a div the mouse cursor came from?

Currently i'm using this method:

offset_pos_x = parseInt(e.offsetX);
offset_pos_y = parseInt(e.offsetY);

Then i look for the distances the mouse went inside the div, in which direction.

The Problem is, this method is a bit buggy because i need all 4 sides, not just two, so i have to check offsetX AND offsetY.

If i move the mouse inside the div for example X:+15,Y:-3 (in Pixels) i know that the mouse came from left, because the mouse moved 15px on x-axis, but only -3px on y-axis. The buggy thing about this is, when X and Y are nearly the same and i don't know if the mouse came from left or top (for example).

Also, according to my other Question (jQuery: mouseenter/mousemove/mouseover not recognized with small div and fast mouse movement) the Event isn't fired on the first Pixel of the div's side, because of browser/os limitations. Because of that, my "entered_at" coordinate isn't that accurate - example:

If i move my mouse cursor very fast inside the div (from left), the "entered_at" coord is at x:17,y:76 for example. Now if i move my mouse to the left after stoping the mouse, for example to x:6,y:76 the difference between the starting point and offsetX is negative, so the "cursor came from right" function is triggered...

Is there another way to detect the side from which the mouse cursor came from?



I wouldn't use the offset, but rather pageX/pageY (jQuery normalizes these). If the cursor's first mousemove event was closer to the left edge than any other edge, it came from the left. You may also consider using the hover event for this, rather than mousemove.

JSFiddle, courtesy of the Jamaican flag.

function closestEdge(x,y,w,h) {
        var topEdgeDist = distMetric(x,y,w/2,0);
        var bottomEdgeDist = distMetric(x,y,w/2,h);
        var leftEdgeDist = distMetric(x,y,0,h/2);
        var rightEdgeDist = distMetric(x,y,w,h/2);
        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";

function distMetric(x,y,x2,y2) {
    var xDiff = x - x2;
    var yDiff = y - y2;
    return (xDiff * xDiff) + (yDiff * yDiff);