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

我正在尝试模拟我hover在图像上的效果,覆盖的半透明图像将从鼠标来自的方向淡入。 鼠标离开图像时反之亦然(淡出+移开)

我为此准备了一个测试页面 。 继续检查,它将阐明所需的效果。

我为此定义了一个HTML结构:

 

和以下的JS(我正在使用jQuery):

 jQuery(document).ready(function () { ourWork(); }); function ourWork(){ var inHandler = function(){ var blue_bg = jQuery(this).find('.overlayLink_overlay_bg'); var divClass = inClass; blue_bg.stop(true,true).fadeIn(); var ml,mt; if(divClass == 'left'){ ml = -260; mt = 0; } else if(divClass == 'right'){ ml = 260; mt = 0; } else if(divClass == 'top'){ ml = 0; mt = -140; } else if(divClass == 'bottom'){ ml = 0; mt = 140; } //positioning jQuery(this).find('a').css({ 'marginLeft': ml + 'px', 'marginTop' : mt + 'px' }); //animation jQuery(this).find('a').stop(true,true).animate({ "marginLeft": "0px", "marginTop": "0px" }, "slow"); } var outHandler = function(){ var blue_bg = jQuery(this).find('.overlayLink_overlay_bg'); var divClass = outClass; blue_bg.stop(true,true).fadeOut(); var ml,mt; if(divClass == 'left'){ ml = -260; mt = 0; } else if(divClass == 'right'){ ml = 260; mt = 0; } else if(divClass == 'top'){ ml = 0; mt = -140; } else if(divClass == 'bottom'){ ml = 0; mt = 140; } //animation jQuery(this).find('a').stop(true,true).animate({ "marginLeft": ml + "px", "marginTop": mt + "px" }, "slow"); } var inClass, outClass; jQuery('.overlayLink_overlay_fg div').hover(function(){ inClass = jQuery(this).attr('class'); },function(){ outClass = jQuery(this).attr('class'); }); jQuery('.overlayLink').mouseenter(inHandler).mouseleave(outHandler); } 

说明:

基本上我在图像顶部有四个绝对定位的div来知道当我hover在其中一个div(.overlayLink_overlay_fg div)时的方向(左,上,下,右)我把hover的div的类名放在一个变量(var inClass和var outclass)

一旦我将鼠标hover在覆盖图像区域的div(.overlayLink)上,我就从inClass或outClass变量请求方向并执行动画(inHandler,outHandler)

但是这一切似乎都有效,当你快速移动你的鼠标时,它有点小问题, 现在我问的问题是什么(导致故障)以及如何用我当前的代码修复它。

提前致谢

也许你应该考虑不要将div用作“热点”,而是使用一些Math和Javascript来找到鼠标进入并离开div的点。 这避免了重叠/间隙问题。 basicaly下面的代码在4个三角区域中划分div。 当鼠标移过它时,每个区域都会返回一个数字。 代码需要一些微调,你必须自己决定绑定和取消绑定事件的位置。 但我认为这会消除你大部分的闪烁问题。

 $(".overlayLink").bind("mouseenter mouseleave",function(e){ /** the width and height of the current div **/ var w = $(this).width(); var h = $(this).height(); /** 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 - this.offset().left - (w/2)) * ( w > h ? (h/w) : 1 ); var y = (e.pageY - this.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: /** animations from the TOP **/ break; case 1: /** animations from the RIGHT **/ break; case 2: /** animations from the BOTTOM **/ break; case 3: /** animations from the LEFT **/ break; }}); 

当然,获得方向的简短符号应该是:

 var direction = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4 

其中1.57 …是Math.PI / 2这对我来说更难以解释,因为它会跳过度转换。

从根本上说,鼠标移动事件发生的是一系列点,而不是像我们感知屏幕上的移动那样的曲线。 移动鼠标的速度越快,点之间的间距越大,鼠标移动的对象越大而不会触碰。 理想情况下,您需要知道在着陆到对象之前最后一个鼠标位置的方向,并从中计算出它接近的方向。 即你需要不断跟踪整个页面上的鼠标位置,以确保每次都能正常工作。

您可以尝试使用图像映射,将处理程序附加到定义的区域,而不是使用绝对定位的div来覆盖图像。 只需将边界区域定义为足够厚,即使它移动得相当快,也可以检测到鼠标移动。

如果您从左向右快速滑动鼠标,使其穿过3个矩形

  [ 1 ] [ 2 ] [ 3 ] 

鼠标通过右边框div退出矩形#2后,立即通过左边框div输入矩形#3。 但是,当通过其左边界div输入矩形#3时,分配inClass =“left”outClass =“left”发生在矩形#2的outHandler被触发之前。

如果我要实现这个function,这就是我如何处理它:

  1. 创建定义图像顶部,底部,左侧和右侧边框的图像映射区域。
  2. 对于你想要这种智能的每个图像(即它输入的是哪一侧,它离开了哪一侧):a)跟踪sideEntered – 这个值只分配一次; 每当进入图像 – 地图边界区域时,其鼠标hover处理程序将参考sideEntered并仅在尚未分配时指定它 ; b)跟踪lastSideTouched – 每当输入图像映射区域时,mouseoverhandler重新分配此变量c)当鼠标离开矩形时,leave处理程序查询lastSideTouched并将sideEntered重置为null

每个矩形都应该有自己的处理程序,因此两个重要的值sideEnteredlastSideTouched封装在其处理程序的范围内。

  • 问题是什么(导致故障)

此代码(以及inClass和outClass的使用)存在问题。 您正在更改事件处理程序中使用的全局变量的状态。

 var inClass, outClass; jQuery('.overlayLink_overlay_fg div').hover(function(){ inClass = jQuery(this).attr('class'); },function(){ outClass = jQuery(this).attr('class'); }); 

此代码假定outClass由“local”div设置,但coulsd已由相邻的top div设置

  var outHandler = function(){ var blue_bg = jQuery(this).find('.overlayLink_overlay_bg'); var divClass = outClass; 
  • 如何使用我当前的代码修复它?

不要将其作为单个全局变量进行管理,尝试使用Isolated mannor进行管理。

这是一个apprach:我没有测试过这段代码

  jQuery('.overlayLink_overlay_fg div').hover(function() { jQuery(this).parents('.overlayLink').attr('mouseEnterClass', jQuery(this).attr('class')); }, function() { jQuery(this).parents('.overlayLink').attr('mouseLeaveClass', jQuery(this).attr('class')); }); 

在您的处理程序中,请参考这些新数据。

  var outHandler = function() { var blue_bg = jQuery(this).find('.overlayLink_overlay_bg'); var divClass = jQuery(this).attr('mouseLeaveClass'); .... } 

这个woulod解决了全局变量问题。 我不确定如果’hover’事件在动画完成之前发生会发生什么。

编辑:修复了代码问题。