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

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

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

jQuery(this).bind('mousemove',function(e){ offset_pos_x = parseInt(e.offsetX); offset_pos_y = parseInt(e.offsetY); ... 

然后我寻找鼠标进入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之间的差值为负,所以触发了“光标来自右边”function……

有没有其他方法可以检测鼠标光标来自哪一侧?

问候,帕特里克

我不会使用偏移量,而是使用pageX / pageY(jQuery规范化这些)。 如果光标的第一个mousemove事件比任何其他边缘更接近左边缘,则它来自左边。 您也可以考虑使用hover事件,而不是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); } 

这是脚本的正确/工作示例,包括绝对定位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+'

'); }); }); 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("
" + msg + "

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

牙买加国旗小提琴中最接近的边缘function并不尽如人意,并且对于某些元素来说是不准确的。 我们可以使用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"; } } 

例如:

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

我对这段代码有一些问题,当在一个矩形上操作时,我发现当它应该是顶部时,它会错误地将边缘识别为正确。 我花了一些时间想出答案,觉得我会分享:

 var getDir = function( elem, e ) { /** the width and height of the current div **/ var w = elem.width(); var h = elem.height(); var offset = elem.offset(); /** calculate the x and y to get an angle to the center of the div from that x and y. **/ /** gets the x value relative to the center of the DIV and "normalize" it **/ var x = (e.pageX - offset.left - (w/2)) * ( w > h ? (h/w) : 1 ); var y = (e.pageY - offset.top - (h/2)) * ( h > w ? (w/h) : 1 ); /** the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);**/ /** first calculate the angle of the point, add 180 deg to get rid of the negative values divide by 90 to get the quadrant add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/ var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180 ) / 90 ) + 3 ) % 4; /** do your animations here **/ switch(direction) { case 0: return 'top'; break; case 1: return 'right'; break; case 2: return 'bottom'; break; case 3: return 'left'; break; } } $(this).bind('mouseenter',function(e){ //outputs the direction to the log console.log(getDir($(this), e)); }); 

credit: 用于’鼠标方向’hover的jQuery动画

这是一个插件

: https : //github.com/JohnnyBeGood34/JQuery-MouseEntrance

希望能帮助你。

我使用jQuery函数改进了@Patrick的解决方案,以获得更加优雅和强大的自定义jQuery函数。

这是jQuery getMouseSide jsFiddle :

 $(function () { $('img').hover(function (event) { log('entered at: ' + $(this).getMouseSide(event)) }, function (event) { log('left at: ' + $(this).getMouseSide(event) + '

') }) $.fn.getMouseSide = function (event) { function distanceMetric(x, y, x2, y2) { return Math.pow(x - x2, 2) + Math.pow(y - y2, 2) } function closestEdge(x, y, w, h) { var edgeDistance = { top: distanceMetric(x, y, w / 2 , 0) , bottom: distanceMetric(x, y, w / 2 , h) , left: distanceMetric(x, y, 0 , h / 2) , right: distanceMetric(x, y, w , h / 2) } , edgeDistances = $.map(edgeDistance, function (value) { return [value] }) return Object.keys(edgeDistance)[ $.inArray( Math.min.apply(null, edgeDistances) , edgeDistances ) ] } var current = $(this) , elementOffset = current.offset() return closestEdge( event.pageX - elementOffset.left , event.pageY - elementOffset.top , current.width() , current.height() ) } }) function log(message) { $('#console').append('
' + message + '

') }