javascript中mouseover、mouseout使用详解
本文并没有像标题说的那样,真正阻止事件元素的子元素冒泡...
只是在子元素冒泡到事件元素处时进行了一个判断,判断是否要触发事件,哦...不对应该是是否要运行事件函数中的相关操作...
首先你可以猛戳这里:问题的出现
注:jquery中的mouseover/out事件也有此问题
解决方法一:
在ie下有mouseenter与mouseleave事件来替代mouseover和mouseout。
网上很多说法,这两个事件只有ie支持,其他浏览器不支持。
但是我在最新版本的火狐与谷歌都支持了mouseenter与mouseleave!!!!!
另外ie是的支持范围是:[ie5+,所以我们还是别喷ie了...
其他浏览器测试了下:
在Firefox/3.6.28是不支持mouseenter与mouseleave的,Firefox具体从哪个版本开始支持这两个事件,就不得而知了...
在Opera9.50Alpha与Opera9.00Beta都不支持。其实Opera现在完全可以不要测试了,最新版的Opera都是webkit内核...
谷歌低版本未测试...
当然这些老版本浏览器基本可以不用管了,所以这应该是最好的解决办法了:用mouseenter与mouseleave事件来替代mouseover和mouseout。
此二事件的实例戳这:mouseenter与mouseleave
注:jquery中也有mouseenter与mouseleave事件,兼容所有浏览器。
解决方法二:
上面那个方法在老版本的火狐与谷歌是不支持的,如果你希望得到最大范围的兼容,那可以继续往下看
我们利用varreltg=e.relatedTarget?e.relatedTarget:e.type=='mouseout'?e.toElement:e.fromElement来获取事件相关元素。再通过这个事件相关元素它跟事件元素的关系(包含的关系),来判断是否做相关事件处理。
对于mouseout事件来说,reltg就是鼠标指针离开目标时,鼠标指针进入的节点。
对于mouseover事件来说,reltg就是鼠标指针移到目标节点上时所离开的那个节点。
在li的mouseout的事件函数中,如果reltg为li的子元素我们就不要运行相关操作,如果reltg为li的父元素就运行相关操作。
我们可以通过下面的isMouseLeaveOrEnter函数来判断li与reltg的包含关系:
//判断事件相关元素与li的关系如果事件相关元素为li的子元素就返回false反之返回true functionisMouseLeaveOrEnter(e,handler){ if(e.type!='mouseout'&&e.type!='mouseover')returnfalse; varreltg=e.relatedTarget?e.relatedTarget:e.type=='mouseout'?e.toElement:e.fromElement; while(reltg&&reltg!=handler)reltg=reltg.parentNode; return(reltg!=handler); }; Li.onmouseout=function(e){ e=e||window.event; if(isMouseLeaveOrEnter(e,this)){ //运行相关操作 }; }
此方法明显的缺点就是isMouseLeaveOrEnter中要遍历所有的父元素了,性能问题
解决方法三:
此方法与方法二其实思路是一样的,只是我们这里通过compareDocumentPosition/contains来判断li与reltg的包含关系,优化了方法二遍历所有父元素带来的性能问题。
直接看代码吧:
//判断node是否为parent的子元素 //ifnode==parent也会返回true functioncontains(parent,node){ if(parent.compareDocumentPosition){//ff var_flag=parent.compareDocumentPosition(node); return(_flag==20||_flag==0)?true:false; }elseif(parent.contains){//ie returnparent.contains(node); } }; Li.onmouseout=function(e){ e=e||window.event; varrelatedEle=e.relatedTarget?e.relatedTarget:e.type=='mouseout'?e.toElement:e.fromElement if(!contains(this,relatedEle)){ show.innerHTML=show.innerHTML+'0'; } }
compareDocumentPosition()方法比较两个节点,并返回描述它们在文档中位置的整数。
返回值可能是:
1:没有关系,两个节点不属于同一个文档。
2:第一节点(P1)位于第二个节点后(P2)。
4:第一节点(P1)定位在第二节点(P2)前。
8:第一节点(P1)位于第二节点内(P2)。
16:第二节点(P2)位于第一节点内(P1)。
32:没有关系,或是两个节点是同一元素的两个属性。
注释:返回值可以是值的组合。例如,返回20意味着在p2在p1内部(16),并且p1在p2之前(4)。
而[ie8-不支持compareDocumentPosition()方法,需要用contains代替compareDocumentPosition()方法那么强大,它是用来确定nodeB是否包含在另一个 nodeA中:nodeA.contains(nodeB)
以上所述就是本文的全部内容了,希望大家能够喜欢。