第一次写文,大神请绕路,求轻喷~~
先给个简单的布局,先是HTML
<body> <div id="outer"> <div id="inner"> </div> </div> </body>
然后是CSS
#outer{ width:400px; height:400px; background-color:red; margin:10px auto; position:relative;} #inner{ width:100px; height:100px; background-color:yellow; position:absolute; left:150px; top:150px;}
这时候页面上看到的布局是这样的
不要在意丑不丑,仅仅意思一下。。
var oOuter = document.getElementById('outer'); var oInner =document.getElementById('inner'); oOuter.onmouseover = function(){ this.style.background = 'blue'; } oOuter.onmouseout = function(){ this.style.background = 'red'; }
简简单单给外层DIV添加了鼠标移入移出事件,然后我们回到页面尝试一下,发现一点问题也没有,移入时候外层DIV颜色变蓝,移出去变回红色
但是我们如果再加上一句话
oInner.onmouseover = function(e){ e.stopPropagation(); //或者是alert(1); }
此时每当我们鼠标移入到黄色DIV的时候,我们发现了外层DIV由蓝色变红了,这是因为鼠标进入子元素的触发了父元素的mouseout事件
之前正常是因为事件冒泡,其实父元素也变色了,不过速度很快人眼没有察觉
此时就要吐槽一下safari了,如果用alert(1)这种阻塞查看的话,父元素还是蓝色!!猜测和浏览器渲染机制有关吧,自己不懂
现在看起来没什么问题,因为反正人眼看不出来
可是如果mouseover和mouseout触发的是定时器导致元素的位置变化啊之类的效果,那么就会有非常不好的用户体验了
那该如何解决?
最简单的方法就是使用mouseenter和mouseleave,这两个事件不会因为鼠标从父元素移到子元素就balabala乱来一通,只要你鼠标还在父级里面,怎么跑,也不会触发mouseleave
然后好消息是连IE6都兼容!坏消息是safari不兼容!
这只能手动判断了,下面给出两个方法
aElement.contains(bElement)和aElement.compareDocumentPosition(bElement)
先说contains方法,这个很简单,判断bElement是否在aElement内部
代码如下
oOuter.onmouseout = function(e){if(this.contains(e.relatedTarget)){ return ; } this.style.background = 'red'; }
注意:有些浏览器(大部分,除了FF之外还支持e.toElement),不过最好用relatedTarget,这个是标准的
然后就会发现问题没有了~
下面说我更喜欢也是更强大的compareDocumentPosition方法,先给出一张图~
何止是只能判断一个元素是否在一个元素之中啊,这完全是判断两个元素文档之间的位置关系啊,非常强大有木有~
高版本浏览器都支持此方法,修改代码如下
oOuter.onmouseout = function(e){ if(this.compareDocumentPosition(e.relatedTarget) == 20){ return ; } this.style.background = 'red'; }
注意:contains虽然不够强大,不过兼容IE6,而compareDocumentPosition只能兼容高版本浏览器
结语:第一次写好累啊,不过希望坚持下去,多将自己一些经历写出来,是对自己的锻炼,也是算帮助一下起步者。。。(明明自己也是才起步)