mouseover、mouseout停止事件冒泡的解决方案

来源:互联网 发布:zara知乎 编辑:程序博客网 时间:2024/05/02 05:06

      

        文章来源:   寒云路几层的博客 link : http://vs.net2005.blog.163.com/blog/static/77528105200952310565624/


  在IE里有onmouseleave和onmouseenter,可以解决停止事件冒泡。然而,在其他兼容的各大浏览器中,却没有这两个事件。

  在各类浏览器中,都有onmouseover和onmouseout事件。但是,这两个事件却无法做到停止事件冒泡。

  一、问题产生

  我们现在来看一个示例,从而理解事件冒泡的作用。


 <div id="div1" onmouseout="hidediv('div2');">
    <input id='button1' onclick="showdiv('div2')";value="显示" />
    <div id="div2">
      <table>
        <tr><td>sdsdfsdf</td></tr>
        <tr><td>sdsdfsdf</td></tr>
      </table>
    </div>
</div>


我们希望通过上述代码,获得如下的效果:
  ①当点击按钮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" onmouseout="if (isMouseLeaveOrEnter(event,this)) hidediv('div2');">
    <input id='button1' onclick="showdiv('div2')";value="显示" />
    <div id="div2">
      <table>
        <tr><td>sdsdfsdf</td></tr>
        <tr><td>sdsdfsdf</td></tr>
      </table>
    </div>
</div>