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></l

在做一个二级菜单的时候,遇到这样的问题。先写一个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&quot  ;

                clearTimeout(timeOutVar);

            }

            lastLi=$(this).next('div');

            lastLi.css("display","block&quot  ;},

       function(){

       timeOutVar=setTimeout('lastLi.css("display","none&quot  ',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&quot;',1500);

}).mouseover(function(){

    if(timeOutVar!=null)clearTimeout(timeOutVar);

   timeOutVar=null;

   }

);


方法二:使用jquery中的bind方法(jquery的版本至少要1.2.2)。


$('ul>li>div').bind("mouseenter",function(){}) 代替 $(...).mouseover();


$('ul>li>div').bind("mouseleave",function(){}) 代替 $(...).mouseout();


因为bind方法可以屏蔽浏览器的一些事件冒泡行为。


这样,就不会出现刚刚所说的mouseover,mouseout错误触发的问题。


另外,ie支持mouseenter,mouseleave事件,firefox等不支持,但通过jquery的这种方式后,所有浏览器均支持上面的语法(这大概也是jquery的好处吧)


有用  |  无用

猜你喜欢