我写的方法是网上的前辈做出来,我在这说说我自己遇到的问题。html和css代码就不贴了,就是4个div做测试用的。
下面是完整代码,基本兼容各大流行浏览器。
function mouse(obj,str,e){
var x = e.offsetX, y = -e.offsetY;
var k = Math.round(-obj.height()/obj.width()*100)/100; // 斜率 Math.round(*100)/100
var x0 = Math.round(obj.width()/2*100)/100,
y0 = Math.round(-obj.height()/2*100)/100;
var kx = Math.round((y-y0)/(x-x0)*100)/100;
if(isFinite(kx) && kx > k && kx < -k){
flag = x-x0 > 0 ? 1 : 0;
guide(flag,obj,str);
}
else{
flag = y-y0 > 0 ? 2 : 3;
guide(flag,obj,str);
}
}
function guide(x,obj,str){
var top = 0, left = 0;
var top1 = 0, left1 = 0;
if(str == '进'){
switch(x){
case 0 : top = 0; left = -200; break;
case 1 : top = 0; left = 200; break;
case 2 : top = -200; left = 0; break;
case 3 : top = 200; left = 0; break;
}
top1 = 0;
left1 = 0;
}
else{
switch(x){
case 0 : top1 = 0; left1 = -200; break;
case 1 : top1 = 0; left1 = 200; break;
case 2 : top1 = -200; left1 = 0; break;
case 3 : top1 = 200; left1 = 0; break;
}
top = 0;
left = 0;
}
// stop() 解决鼠标运动过快,动画在事件结束后仍持续执行的问题
switch(x){
case 0 : obj.css({top:top+'px',left:left+'px'}).stop().animate({top:top1+'px',left:left1+'px'},"swing").html('鼠标由左'+str);
break;
case 1 : obj.css({top:top+'px',left:left+'px'}).stop().animate({top:top1+'px',left:left1+'px'},"swing").html('鼠标由右'+str);
break;
case 2 : obj.css({top:top+'px',left:left+'px'}).stop().animate({top:top1+'px',left:left1+'px'},"swing").html('鼠标由上'+str);
break;
case 3 : obj.css({top:top+'px',left:left+'px'}).stop().animate({top:top1+'px',left:left1+'px'},"swing").html('鼠标由下'+str);
break;
}
}
$('.fat').on('mouseenter',function(e){
var e = window.event || e;
mouse($(this).find('.son'),'进',e);
})
$('.fat').on('mouseleave',function(e){
var e = window.event || e;
mouse($(this).find('.son'),'出',e);
})
现在来说说我遇到的问题,对于事件对象大家都知道,FF和IE的获取方式略有不同,我们基本采用这种方式
function (e) { var e = window.event || e } ;我之前的代码是这样写得:
我将e放入mouse函数中,自以为可以获取鼠标对象,可是在FF下,e is not defiend;
好了,开始一步步排查错误:
1. 在FF下获取事件对象,function必须有参数e,所以从表面来看function mouse()是没有问题的,那么会是传参顺序的问题吗?
2. 在 js中 函数的参数没有签名,也没有形参与实参一一对应的限制,函数体是通过arguments 对象来访问参数,在个对象类似于数组,函数会从0 -- length读取参数
(arguments[0]是对一个参数,arguments[1]是第二个参数,以此类推),然会取相对应的参数进行操作。 所以图中 实参两个,形参三个,并不会有什么问题。
3. 在 mouse 函数中执行 var e = window.event || e; 在FF中却有e is not defiend 的报错,但在IE,猎豹下执行并不会出错,这就证明了js参数并不需要一一对应的关系,
也说明 e 在mouse中并没有发挥作用。
4. 再仔细看代码,mouseenter 事件 其实绑定在 function(){} 上,所以 mouse 不能获取事件对象, 所以应当更改代码为文章开头的代码,先获取 鼠标对象,再当参数传入
mouse 中,方可解决 FF 中的问题。
虽然我的问题说起来比较low ,可以说是有点可笑,但当时确实困扰我时间比较长,我把重点全放在了 事件对象的兼容性问题上,并没有想到事件绑定的作用域的问题。