1)最近在写菜单栏的时候,用到了js的mouseover事件,发现了一些问题。
当添加事件的容器里面没有其他任何子容器的时候,一切就正常
但是呢,如果父容器里面有子容器,那么鼠标在子容器间切换移动的时候都会触发原本是添加在父容器上的mouseout事件(即使只是在子容器间移动,并没有out出父容器)
2)一开以为是事件冒泡的问题,但后来测试后发现好像不是。
猜测:虽然事件添加在currentTarget上,但是currentTarget只是被注册事件监听器的对象,target才是真正的事件,所以是target触发了事件,所以才有了上面#top 跟#bottom触发了mouseout事件
3)所以,解决的方法就是判断relatedTarget对象是否是currentTarget的子节点或者本身,如果不是,才放置触发要做的事件
4)以下为测试所用代码(解决这个问题的时候,上网查,看的是这篇文章http://www.qiqiboy.com/2011/01/19/javascript-mouseover-and-mouseout.html,不过里面有些些地方不是很赞同,我的测试代码其实就是参考他的代码的 )
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>aboutMouseout</title> 5 <meta charset="utf-8" /> 6 <style type="text/css"> 7 body{ 8 margin: 0; 9 padding: 0; 10 } 11 #container{ 12 height: 200px; 13 width: 200px; 14 background-color: red; 15 color:white; 16 font-size: 20px; 17 font-weight: bold; 18 text-align: center; 19 } 20 #top{ 21 height: 60px; 22 width: 200px; 23 padding-top: 40px; 24 background-color: green; 25 } 26 #bottom{ 27 height: 60px; 28 width: 200px; 29 padding-top: 40px; 30 background-color: blue; 31 } 32 </style> 33 </head> 34 <body> 35 <div id="container"> 36 <div id="top">top</div> 37 <div id="bottom">bottom</div> 38 </div> 39 <script type="text/javascript"> 40 var EventUtil = { 41 addHandler: function (element, type, handler) { 42 if (element.addEventListener) { 43 element.addEventListener(type, handler, false); 44 } else if (element.attachEvent) { 45 element.attachEvent("on" + type, handler); 46 } else { 47 element["on" + type] = handler; 48 } 49 }, 50 getEvent: function (event) { 51 return event ? event : window.event; 52 }, 53 getTarget: function (event) { 54 return event.target || event.srcElement; 55 }, 56 getRelatedTarget: function (event) { 57 if (event.relatedTarget) { 58 return event.relatedTarget; 59 } else if (event.toElement) { 60 return event.toElement; 61 } else if (event.formElement) { 62 return event.formElement; 63 } else { 64 return null; 65 } 66 } 67 } 68 //返回值布尔值,判断childNode是否是parentNode的子节点 69 function contains(parentNode,childNode){ 70 if(typeof parentNode.contains==="function"){ 71 return parentNode.contains(childNode); 72 }else if(typeof parentNode.compareDocumentPosition==="function"){ 73 return !!(parentNode.compareDocumentPosition(childNode)&16); 74 }else{ 75 var node=childNode.parentNode; 76 do{ 77 if(node===parentNode){ 78 return true; 79 }else{ 80 node=node.parentNode; 81 } 82 }while(node!==null); 83 return false; 84 } 85 } 86 //返回值布尔值,判断是否触发事件 87 function fixedMouse(event,element){ 88 event=EventUtil.getEvent(event); 89 var related, 90 type=event.type.toLowerCase(); 91 if(type==="mouseover"||type==="mouseout"){ 92 related=EventUtil.getRelatedTarget(event); 93 }else return true; 94 console.log("relatedTarget对象为:#"+related.id); 95 return related && related.prefix!='xul' &&
!contains(element,related) && related!==element; 96 } 97 EventUtil.addHandler(document.getElementById("container"),"mouseout",function(event){ 98 event=EventUtil.getEvent(event); 99 var target=EventUtil.getTarget(event), 100 currentTarget=event.currentTarget; 101 if(fixedMouse(event,this)){ 102 //放置触发事件 103 console.log(event.type+"事件被触发\n"+"事件处于(1、捕获阶段,2、目标对象,3、冒泡阶段):"+
event.eventPhase+"\n事件的实际目标target:#"+target.id+
"\n事件的this对象currentTarget:#"+currentTarget.id); 104 }else{ 105 //不放置触发事件 106 console.log("不是currentTarget对象不放置触发事件\n"); 107 } 108 109 }); 110 </script> 111 </body> 112 </html>