mouseover、mouseout停止事件冒泡的解决方案
在IE里有onmouseleave和onmouseenter,可以解决停止事件冒泡。然而,在其他兼容的各大浏览器中,却没有这两个事件。
在各类浏览器中,都有onmouseover和onmouseout事件。但是,这两个事件却无法做到停止事件冒泡。
一、问题产生
我们现在来看一个示例,从而理解事件冒泡的作用。
<div id="div1" οnmοuseοut="hidediv('div2');"> |
我们希望通过上述代码,获得如下的效果:
①当点击按钮button1时,呈现div2的内容[通过showdiv('div2')这个函数,完成呈现前的定位等处理。这里不做具体描述]。
②当鼠标离开div1时,隐藏div2[通过hidediv('div2')这个函数,完成对div2的隐藏。这里也不做具体描述。]
③当在button1上点击完鼠标后,鼠标可以移动到div2中。
在上述功能中,如果使用onmouseleave,可以非常方便地解决所需的问题。然而,onmouseleave不是一个适合所有浏览器的事件。
当使用onmouseout事件时,当我们点击button1按钮后,会呈现div2,但是,当我们把鼠标移出button1后(不是div1),div2就将消失!这不是我们所期望的。
这也就是事件冒泡!当在外层定义了一个事件后,该事件也会传递到该层的内部的元素上!
二、解决方案
解决停止冒泡问题,在各浏览器中已经有相应的解决方案,但是对于mouseover和mouseout却显得力不从心。
而对于要兼容各大浏览器的Web开发人员来说还是一件头疼的事。
虽然网上已经有针对Mozilla Firefox的一些计策,但代码量也是不容乐观的。
想寻求比较好的解决方案,于是就翻遍了国内的大小网站,终一无所获,不得不硬着头皮去读国外网站,结果是理想的,因为W3C里有relatedTarget,于是就有了下边的解决方案:
Javascript代码
function isMouseLeaveOrEnter(e, handler) { if (e.type != 'mouseout' && e.type != 'mouseover') return false; var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement; while (reltg && reltg != handler) reltg = reltg.parentNode; return (reltg != handler); } |
该函数有两个参数:第一个是一个事件。在IE中,可以在函数内部直接获得事件,而对于FF等,则必须进行事件的传递;第二个参数,是事件定义的元素,也就是说,该事件是对那个元素产生影响。
三、使用用法
在onmouseover和onmouseout里做如上判断。
在需要使用onmouseout的页面上,加上上述的函数,然后在调用的地方,做如下处理(红色部分):
<div id="div1" οnmοuseοut="if (isMouseLeaveOrEnter(event,this)) hidediv('div2');"> |