mouseout mouseover的问题及解决方法(with jquery)
作者:会飞的
在做一个二级菜单的时候,遇到这样的问题。先写一个HTML,方便理解
<ul>
<li><a>LinkA</a>
<div><ul>
<li><a>LinkA_1</a></li>
<li><a>LinkA_2</a></li>
<li><a>LinkA_3</a></li>
</ul></div>
</li>
<li><a>LinkB</a>
<div><ul>
<li><a>LinkB_1</a></li>
<li><a>LinkB_2</a></li>
<li><a>LinkB_3</a></li>
</ul></div>
</li>
</ul>
以上为html基本框架
CSS方面,将内嵌的div设置为absolute,display为none.其它的设置就取决于你的要求。
思路:当鼠标移动到一级分类如:linA时,显示二级菜单。这里我们采用hover或者onmouseover,onmouseout来实现。
需要注意的是,ie6对a:hover支持,其它比如li:hover就不行(这个问题让我费了一天的劲),所以如果你要用hover来实现,就应该将所有内容用a来包括住。
由于二级菜单显示出来了,那么如果你鼠标想移动到二级菜单上,那么会使得一级菜单的mouseout或者hover触发,结果就是二级菜单在你的鼠标还没有移上去时,就消失了=,=
在这里,我使用了setTimeout来解决这个问题
代码如下:
var lastLi=null;
var timeOutVar=null;
$(document).ready(function(){
$('ul>li>a').hover(
function(){
if(lastLi!=null){
lastLi.css("display","none" ;
clearTimeout(timeOutVar);
}
lastLi=$(this).next('div');
lastLi.css("display","block" ;},
function(){
timeOutVar=setTimeout('lastLi.css("display","none" ',1500);
}
);
上面这段代码就是在鼠标移出时,将二级菜单的消失设置为延迟1500执行
现在进入正题,即mouseout,mouseover的问题
二级菜单即可以使用这样的代码:
$('ul>li>div').mouseover(function(){取消延时})
.mouseout(function(){隐藏二级菜单});
结果发现,在鼠标移到二级菜单的时候,二级菜单还是消失了!
原因如下(一句话,浏览器事件冒泡造成的bug):当鼠标移动到div里面的元素如ul上时,浏览器理解为div的mouseout,紧接着,div的mouseover被触发,而我们要求的是,只要鼠标还在div内,mouseout就不应该被触发。
这个bug不仅仅存在于div内嵌元素,还存在于其它元素,比如li(我推测所有的html元素都受这个影响,因为没有时间去验证,所以在这里仅表示推测)。
如何解决?我们知道了原因,不过最后我们还是要想怎么解决,虽然说浏览器的bug,不过最后还是得我们去买帐。
方法一:这个方法是我最初想到的方法。核心思路是:setTimeout.即延迟执行。
即在mouseout时,延迟执行隐藏菜单,而在mouseover时,取消延迟执行。这样因为mouseover总是后触发,所以我们就能得到要的效果。复制一下我实际中写的代码:
$('ul>li>div').mouseout(function(){
clearTimeout(timeOutVar);
timeOutVar=setTimeout('lastLi.css("display","none"',1500);
}).mouseover(function(){
if(timeOutVar!=null)clearTimeout(timeOutVar);
timeOutVar=null;
}
);
方法二:使用jquery中的bind方法(jquery的版本至少要1.2.2)。
$('ul>li>div').bind("mouseenter",function(){}) daiti代替 $(...).mouseover();
$('ul>li>div').bind("mouseleave",function(){}) daiti代替 $(...).mouseout();
因为bind方法可以屏蔽浏览器的一些事件冒泡行为。
这样,就不会出现刚刚所说的mouseover,mouseout错误触发的问题。
另外,ie支持mouseenter,mouseleave事件,firefox等不支持,但通过jquery的这种方式后,所有浏览器均支持上面的语法(这大概也是jquery的好处吧)