jQuery:有没有机会在没有"Offset"方法的情况下检测鼠标从哪一侧进入div?

Pat*_*ick 6 jquery mouseover

有没有办法检测鼠标光标来自div的哪一侧?

目前我正在使用这种方法:

jQuery(this).bind('mousemove',function(e){
    offset_pos_x = parseInt(e.offsetX);
    offset_pos_y = parseInt(e.offsetY);
    ...
Run Code Online (Sandbox Code Playgroud)

然后我寻找鼠标进入div的距离,在哪个方向.

问题是,这种方法有点儿麻烦,因为我需要所有4个边,而不仅仅是两个,所以我必须检查offsetX和offsetY.

如果我在div中移动鼠标,例如X:+ 15,Y:-3(以像素为单位),我知道鼠标是从左侧移动的,因为鼠标在x轴上移动了15px,但在y轴上仅移动了3px .有关这方面的错误是,当X和Y几乎相同时,我不知道鼠标是从左侧还是顶部(例如).

另外,根据我的另一个问题(jQuery:mouseenter/mousemove/mouseover无法通过小div和快速鼠标移动识别),由于浏览器/操作系统的限制,事件不会在div的第一个Pixel上触发.因此,我的"entered_at"坐标不准确 - 例如:

如果我在div(左起)内快速移动鼠标光标,则"entered_at"坐标为x:17,y:76.现在如果我在停止鼠标后将鼠标移动到左边,例如x:6,y:76,起点和offsetX之间的差值为负,所以触发了"光标来自右边"功能......

是否有另一种方法来检测鼠标光标来自哪一侧?

问候,帕特里克

tur*_*yag 10

我不会使用偏移量,而是使用pageX/pageY(jQuery规范化这些).如果光标的第一个mousemove事件比任何其他边缘更靠近左边缘,则它来自左边.您也可以考虑使用悬停事件而不是mousemove.

JSFiddle,由牙买加国旗提供. http://jsfiddle.net/MJTkk/1/

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);
}
Run Code Online (Sandbox Code Playgroud)


Pat*_*ick 8

这是脚本的正确/工作示例,包括绝对定位div的修复.再次感谢您的帮助turiyag!

jsfiddle:http://jsfiddle.net/MJTkk/2/

脚本:

$(function() {
    $("img").hover(function(e) {
        var el_pos = $(this).offset();
        var edge = closestEdge(e.pageX - el_pos.left, e.pageY - el_pos.top, $(this).width(), $(this).height());
        log('entered at: '+edge);
    }, function(e) {
        var el_pos = $(this).offset();
        var edge = closestEdge(e.pageX - el_pos.left, e.pageY - el_pos.top, $(this).width(), $(this).height());
        log('left at: '+edge+'<br><br>');
    });
});

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 log(msg) {
    $("#console").append("<pre>" + msg + "</pre>");
}

function distMetric(x,y,x2,y2) {
    var xDiff = x - x2;
    var yDiff = y - y2;
    return (xDiff * xDiff) + (yDiff * yDiff);
}
Run Code Online (Sandbox Code Playgroud)


chr*_*ead 5

牙买加国旗小提琴中最接近的边缘函数不尽如人意,并且对于某些元素也不准确。我们可以使用offsetXoffsetY简化功能并消除distMetric功能:

// Pass object offsetX,offsetY,width,height
function closestEdge(distLeft,distTop,w,h){
    var distBottom = (h - distTop);
    var distRight = (w - distLeft);
    var min = Math.min(distTop, distBottom, distLeft, distRight);
    switch (min) {
        case distLeft:
            return "left";
        case distRight:
            return "right";
        case distTop:
            return "top";
        case distBottom:
            return "bottom";
    }
}
Run Code Online (Sandbox Code Playgroud)

例如:

$('.btn').on('mouseenter',function(e){
    var edge = closestEdge(e.offsetX, e.offsetY, $(this).width(), $(this).height());
});
Run Code Online (Sandbox Code Playgroud)