zoukankan      html  css  js  c++  java
  • 浏览器中模拟mouseenter omouseleave事件(解决onmouseover onmouseout重复调用)

    一. mouseenter和mouseleave何时被触发


    我们来看下官方解释(mouseentermouseleave):

    // onmouseenter:
    Fires when the user moves the mouse pointer inside the boundaries of an object.
    即:当鼠标移入元素对象的边界之内时,激活该事件

    // onmouseleave:
    Fires when the user moves the mouse pointer outside the boundaries of the object.
    即:当鼠标移出元素对象的边界之外时,激活该事件

    二. 与mouseover和mouseout的区别


    官方站点在介绍mouseenter和mouseleave时,同时说明了与mouseover和mouseout的不同:

    // onmouseenter vs onmouseover
    Unlike the onmouseover event, the onmouseenter event does not bubble. In other words, the onmouseenter event does not fire when the user moves the mouse pointer over elements contained by the object, whereas onmouseover does fire.
    即:onmouseenter不会冒泡,onmouseover则会,由于这个差异,当鼠标在元素边界内移动时,不会激活onmouseenter(只在鼠标进入元素边界内时激活),但会激活onmouseover(当该元素包含子元素时)。

    // onmouseleave vs onmouseout
    同上,由于存在冒泡的差异,导致了鼠标在元素边界内移动时,会激活onmouseout(当该元素包含子元素时),但不会激活onmouseleave。

    三. 为什么要模拟mouseenter和mouseleave?


    原因很简单:相对于mouseover和mouseout,mouseenter和mouseleave具有性能优势(不会反复触发),但只有IE支持它。。。


    四. 如何模拟?


    原理:监听目标元素的mouseover和mouseout事件,只当鼠标移入目标元素时,才执行回调函数,忽略子元素上激活的mouseover和mouseout事件。我们通过事件对象的relatedTarget (ie浏览器为fromElement或toElement)属性,来判断鼠标是移入/移出目标元素,还是在目标元素内移动:


    (1) 当mouseover被激活时,relatedTarget表示鼠标进入目标元素时,是从哪个元素离开的,我们可以对relatedTarget的值进行判断:如果值不是目标元素,也不是目标元素的子元素,就说明鼠标已移入目标元素;


    (2) 当mouseout被激活时,relatedTarget表示鼠标离开目标元素时,进入了哪个元素,我们同样可以对relatedTarget的值进行判断:如果值不是目标元素,也不是目标元素的子元素,就说明鼠标已移出目标元素;

     

     

    五. 实例

    // HTML:
    <ul id="J_List">
       <li><a href="#">item1</a></li>
       <li><a href="#">item2</a></li>
       <li><a href="#">item3</a></li>
    </ul>
    // JS(基于YUI):
    <script type="text/javascript">
       var Y = YAHOO.util,
            Dom = Y.Dom,
            Event = Y.Event;

       // 获取所有的li
       var oList = Dom.get('J_List');

       Event.on(oList, 'mouseover', function(e) {
            var rt = Event.getRelatedTarget(e),
                 curElem = this;

            // 如果rt不是curElem且不是curElem的子元素, 则就是mouse enter的情况
            if (rt !== curElem && !Dom.isAncestor(curElem, rt)) {
                 console.log('enter: ' + curElem.id);
            }
        });

        Event.on(oList, 'mouseout', function(e) {
             var rt = Event.getRelatedTarget(e),
                  curElem = this;

             // 如果rt不是curElem且不是curElem的子元素, 则就是mouse leave的情况
             if (rt !== curElem && !Dom.isAncestor(curElem, rt)) {
                  console.log('leave: ' + curElem.id);
             }
        });
    </script>
  • 相关阅读:
    [转]权限树中Checkbox的操作[Asp.Net2.0]
    [转]IE点击链接没有反应或打开新窗口出现一个空白框(地址栏空白)的解决方法
    [引]VS2005 之 Visual Basic 编程语言介绍
    [文摘20070816]家(周国平)
    Linux 下zip包的压缩与解压
    SOSO发布国内首家高清街景地图 引领地图换代
    VC 获取当前工作目录和执行目录的一些方法
    设置vim 默认显示行号
    利用脚本将文字插入到图片或进行多个图片拼接
    ImageMagick操作合并图像
  • 原文地址:https://www.cnblogs.com/wuwenjie/p/5576723.html
Copyright © 2011-2022 走看看