dunhuangmi 发表于 2013-1-29 08:30:17

mouseover和mouseout的BUG

dunhuangmi的话:记得还是生手时面过某知名公司,题目之一是两个嵌套div,鼠标走对角线经过父与子时究竟会触发几个mouseover和mouseout事件?我当时答错了http://www.agoit.com/images/smiles/icon_cry.gif,下面这篇文章解释了这个问题。
===================================================================
<div class="bct fc05 fc11 nbw-blog ztag js-fs2">描述:
javascript的mouseover和mouseout事件,在绑定元素内部有子元素的情况下,
经过绑定元素时会多次触发mouseover和mouseout事件。
原因:
当鼠标经过或离开子元素的时候,浏览器认为这样也触发了mouseover和mouseout事件
解决办法::
原生javascript:
(修改自jquery)
    var handler = document.getElementById("test2");
    handler.onmouseover = function(e){
            if(checkFather(this,e)){
                console.debug("over");
            }
    }
    handler.onmouseout = function(e){
            if(checkFather(this,e)){
                console.debug("out");
            }
    }
    function checkFather(that,e){
        var parent = e.relatedTarget;
         try {
            while ( parent && parent !== that ) {
                parent = parent.parentNode;
            }
            return (parent !== that);
        } catch(e) { }
    }
原理是判断离开的元素(mouseover时)或者进入的元素(mouseout进入的元素)是不是事件绑定对象本身或者子元素

jquery解决办法:

jquery的mouseenter和mouseleave方法已经修复了这个问题,可以直接用来替代mouseover和mouseout

不过有个mouseenter和mouseleave有个小问题是,让鼠标从文档外直接进入绑定事件的元素时,mouseenter不生效

暂时解决办法是,别让绑定事件的元素靠浏览器边缘,尽量留出至少1px间距。

另外,jquery的hover()方法,相当于使用了mouseenter和mouseleave。也能解决mouseover和mouseout的问题。
来自:http://www.zhangsuoyong.com/?p=111
 
先了解一下鼠标移动流程,鼠标放上去onmouseover下拉菜单出现,移开onmouseout则消失,从父元素到子元素流程事件触发流程应该是这样的:父onmouseover=>父onmouseout=>子onmouseover...
在 这个过程中有个javascript冒泡的问题,当从父元素移动到子元素的时候,会冒泡到父元素从而触发父元素的onmouseout事件,虽然从界面上 看鼠标并没有移出父元素。所以我们不要冒泡到父元素就行了。纯js的做法就是判断当前元素是否是子元素,是的话,就不冒泡到父元素。
你这里用到了 jQuery的slideDown,使用mouseout时,鼠标只要在容器里一移动,就被触发了hide(),其实是因为mouseout事件也会影响 到子元素,也就是事件可能被同时绑定到了该容器的子元素上,所以鼠标移出每个子元素也都会触发我们的hide()。
jquery1.3版本还有个函数mouseleave,把mouseout换为mouseleave就解决了这个问题。
 
页: [1]
查看完整版本: mouseover和mouseout的BUG