您的位置:首页 > Web前端 > JavaScript

一个鼠标移出事件引发的问题

2016-09-02 16:54 267 查看
一个mouseout事件引发的问题

1. 遇到的问题

最近上课做一个效果,显示一个模拟QQ好友列表,默认是隐藏的,鼠标移动到浏览器右边界的时候显示,离开好友列表框的时候隐藏。

代码如下:

Insert title here

#friends{
border:1px solid #ff0000;
width:200px;
height:400px;
position:absolute;
right:0px;
top:20px;
background: #abcdef;
display:none
}
#line{
width:1px;
height:800px;
float:right;
}

var inter;

jQuery(function(){
/*鼠标移动到右边界线,好友列表框显示*/
("#line").mouseover(function(){
$("#friends").show(1000);
});
/*鼠标离开好友框,隐藏*/("#friends").bind('mouseout',function(event){
$(this).hide(1000);
});

});

好友列表

<div style="height:25px"><span>会飞的鱼</span><img style="width:18px;height:18px;"  src="images/boy.png"/></div>
<div style="height:25px"><span>会飞的鱼</span><img style="width:18px;height:18px;"  src="images/boy.png"/></div>
<div style="height:25px"><span>会飞的鱼</span><img style="width:18px;height:18px;"  src="images/boy.png"/></div>
<div style="height:25px"><span>会飞的鱼</span><img style="width:18px;height:18px;"  src="images/boy.png"/></div>


<div id="line"></div>


运行界面:



上面的mouseout事件出了问题,鼠标移动到右边界显示好友框没问题,当移动到好友昵称上面时候好友框消失了,这是为何?

原因是好友框内有好多子元素div,每个div对应一个好友。此时鼠标移动到子元素上面触发了父元素的mouseout事件。更为糟糕的是子元素div里面还有span,image子元素,这样就会触发子元素div的mouseout,继而冒泡到最外层的好友列表的div。

2. 如何解决

方法一:

思路:判断当前鼠标指向的元素是否是其子元素,如果是子元素就不隐藏,直接return,否则,隐藏好友列表。

给好友列表div注册mouseout代码:

/鼠标离开好友框,隐藏/

(“#friends”).bind(‘mouseout’,function(event){
var tar=event.target || event.srcElement;//鼠标离开的元素
var totar=event.relatedTarget || event.toElement;//鼠标指向的元素
//如果鼠标指向了自己的子元素,则不触发mouseout事件
if((this).find(totar).size()>0||this==totar){

return;

}

//否则,如果不是指向子元素,就表示鼠标已经离开了div

else {

console.log(tar.id+’–’+totar.id);

$(this).hide(1000);

}

});

说明:

在发生mouseover和mouseout事件时,还会涉及更多的元素。这两个事件都会涉及把鼠标指针从一个元素的边界之内移到另一个元素边界之内。对mouseover事件而言,事件的主目标是获得光标的元素,而相关元素就是那个失去光标的元素。类似地,对mouseout事件而言,事件的主目标是失去光标的元素,而相关元素则是获得光标的元素。

DOM通过event对象的relatedTarget属性提供了相关元素的信息。这个属性只对于mouseover和mouseout事件才包含值;对于其他事件,这个属性的值是null。IE不支持realtedTarget属性,但提供了保存着同样信息的不同属性。在mouseover事件触发时,IE的fromElement属性中保存了相关元素;在mouseout事件出发时,IE的toElement属性中保存着相关元素。

以上代码为兼容不同浏览器的写法。如果觉得第一种方法麻烦,可以参照以下方法。

方法二:

思路:给div注册mouseleave事件,该事件和mouseout区别就在于,当鼠标移动到本元素内的子元素的时候不会触发mouseleave,只有真正离开了这个元素才能触发,而且不支持冒泡。

代码:

/鼠标离开好友框,隐藏/

(“#friends”).bind(‘mouseleave’,function(event){(this).hide(1000);

}

);

代码一下子精简了好多。运行结果是一样的。

说明:

mouseover与mouseenter

不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件。

只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件。

mouseout与mouseleave

不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件。

只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件。

官方解释:



M啊啊DN这段解释说只有IE浏览器支持mouseleave和mouseenter事件,其他浏览器暂不支持,火狐其实是支持的,chrome和Safari等浏览器未测试。但我们如果用jQuery注册mouseenter和mouseleave函数,可以支持常见的所有浏览器(均已测试),因为jQuery内部做了封装。写法见上面代码。

3.小结

如果给元素注册鼠标覆盖和离开事件,分两种情况:

1.如果所选元素内没有子元素影响,可以考虑直接用mouseover和mouseout。

2.如果有子元素影响(含有子元素),可以采用mouseenter和mouseleave,防止事件冒泡。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  js事件 冒泡