在做js效果使用到 mouseover、mouseout 效果的时候。常常会遇到鼠标滑动到某个元素内部的时候出现多次触发 mouseover、mouseout 的问题。
如:
<div id="div1"> <div id="div2"></div> </div>
给div1加上一个mouseover、mouseout事件。这个时候当鼠标划入div2再划出div1时会有以下的操作
鼠标划入 div1 触发div1的mouseover
鼠标划入 div2 触发div1的mouseout / 同时 再次触发 div1的mouseover
鼠标划出 div2 触发div1的mouseout / 同时 再次触发 div1的mouseover
鼠标划出 div1 触发div1的mouseout
原因就在于在进入div2时,js一瞬间的bug。这个问题在么解决呢。
在event的dom元素里面有几个比较有用的东西可以解决这个问题。
relatedTarget、fromElement、toElement
fromElement: 表示鼠标从哪个元素来
toElement: 表示鼠标进去哪个元素
如mouseover时:
鼠标从划入div1时:
fromElement:这个时候是body,因为是从body进入div1
toElement: 这个时候是div1,鼠标从body进入div1
当鼠标在div1中划入div2
fromElement:这个时候是div1
toElement: 这个时候是div2
如mouseout时:
鼠标从div2划出到div1时
fromElement:div2
toElement: div1
鼠标从div1划出到body时
fromElement:div1
toElement: body
那么relatedTarget是个什么东西呢?
在mouseover的时候relateTarget = fromElement
在mouseout的时候relateTarget = toElement
那么如何解决进入div2不重复触发 mouseover,mouseout事件呢
当进入div2的时候
mouseover:
fromElement:这个时候是div1
toElement: 这个时候是div2
我们检查fromElement是不是div1或者div1的子集如果是则不作任何操作。此时的fromElement是div1
mouseout:
fromElement:这个时候是div1
toElement: 这个时候是div2
那么我们检查toElement是不是div1或者div1的子集如果是则不作任何操作。此时的mouseout是div2是div1的子集
当离开div2时
mouseover:
fromElement:这个时候是div2
toElement: 这个时候是div1
我们检查fromElement是不是div1或者div1的子集如果是则不作任何操作。此时的fromElement就是div2是div1的子集
mouseout:
fromElement:这个时候是div2
toElement: 这个时候是div1
那么我们检查toElement是不是div1或者div1的子集如果是则不作任何操作。此时的mouseout是div1
问题来了。有人就会想到为什么
mouseout要看toElement而不是fromElement
mouseover要看fromElement而不是toElement
这样也可以啊?
我们接着往下。当鼠标离开div1的时候
mouseout要看toElement:这个时候的toElement是body所以可以判断鼠标离开了div1
如果看fromElement:这个时候的fromElement是div1,所以会出现即时你离开了div1什么事情也没发生
还记得上面提到的relatedTarget 么。
对了。我们要检查的东西 mouseout->toElement,mouseover->fromElement正好和relatedTarget匹配
所以不管是mouseover和mouseout都只要使用relatedTarget去检查就可以了
但是万恶的IE貌似不支持relatedTarget所以写程序的时候用这个代替
if(event.type=="mouseover"){ return event.relatedTarget||event.fromElement; }else{ return event.relatedTarget||event.toElement; }
接下来就简单了。只要判断这个元素是否属于或者等于父级元素。就可以判断鼠标有没有真正的离开过这个元素了。
说到这里就撤个题外话了。
event这个东西是哪里来的呢?
以前看别人的博客、帖子、文章。一般说到这里就结束了。但是没有人会告诉你event这个是什么东西。会弄的别人一知半解。就我的理解来说说event。
event就是事件对象。
怎么获得它?
我有2种方式来获得它
第一种
$('#maintarget').bind('mouseover',function(event){ this //代表$('#maintarget')这个元素 event //代表mouseover这个事件元素 });
第二种
<input type="button" value="ok" onClick="func(this,event)" /> <script> function func(obj,event){ obj //代表input那个元素 event //代表onClick这个事件 } </script>