原文:http://www.quirksmode.org/js/events_mouse.html#relatedtarget

W3C在mouseover和mouseout事件中添加了relatedTarget属性。在mouseover事件中,它表示鼠标来自哪个元素,在mouseout事件中,它指向鼠标去往的那个元素。

而Microsoft添加了两个属性:

  • fromElement在mouseover事件中表示鼠标来自哪个元素。
  • toElement在mouseout事件中指向鼠标去往的那个元素。

跨浏览器的脚本

如果你想知道鼠标来自哪个元素在mouseover事件中,你可以这样写:

1
2
3
4
function doSomething(e) {
  if (!e) var e = window.event;
  var relTarg = e.relatedTarget || e.fromElement;
}

如果你想知道鼠标去往哪个元素在mouseout事件中,你可以这样写:

1
2
3
4
function doSomething(e) {
  if (!e) var e = window.event;
  var relTarg = e.relatedTarget || e.toElement;
}

javascript完美解决onMouseEnter、onMouseLeave、onMouseOver、onMouseOut冒泡事件的一种思路,兼容各种浏览器.

js冒泡事件的产生: 当鼠标移动到div区域内的table、img、a等元素时触法div本身的onmouseout事件. 由于鼠标停留在div标签内部元素上,触发div的onmouseout事件肯定不是我们想要的结果,于是便产生了冒泡事件.

js冒泡事件的解决方法: 当然网上解决的方法有很多,大多代码伸长,不容易理解. 而我们讲的代码非常简短,确容易理解.

原理就是:当触发div的onmouseout事件时,判断触法事件的元素是不是div的子元素,如果是则中断执行即可.

核心代码用到一个contains方法。如果A元素包含B元素,则返回true,否则false。

IE: event.toElement ; // 这个方法用来返回IE下触法事件的元素

非IE: event.relatedTarget;  // 这个方法用来返回非IE下触法事件的元素

代码如下:

<div onmouseout="hiddenObj(event,this);"> <a href=#>冒泡事件超链接</a> </div>

<script type="text/javascript" >

function hiddenObj(theEvent,obj){ //theEvent用来传入事件,Firefox的方式
 var browser=navigator.userAgent;   //取得浏览器属性
 if (browser.indexOf("MSIE")>0){ //如果是IE
           if (obj.contains(event.toElement)) return; // 如果是子元素则结束函数
   }else{ //如果是Firefox
      if (obj.contains(theEvent.relatedTarget)) return; // 如果是子元素则结束函数
}
/*要执行的操作*/
obj.style.display='none';
}

</script>

-----------------------------

话说有一个DIV元素,其内部有一个IMG元素和SPAN元素,不用理会这两个内部元素怎么布局,这不是我要讨论的重点。

为了实现一些特殊的效果,我需要利用TD的onmouseover和onmouseout事件,测试时就会发现如下的状况:

鼠标移入DIV内部时,onmouseover事件被触发;接着再鼠标移动到DIV内部的IMG或者SPAN元素之上,我们肯定不会认为这时鼠标已经移到了DIV的外边,但奇怪的是onmouseout事件触发了,而且紧接着onmouseover事件也马上被触发了。

这可不是我想要的,那么怎么来&ldquo;屏蔽&rdquo;内部元素给外层元素带来的Javascript事件干扰呢?

这里列举两种方法

一. setTimeout

因为在鼠标移动到内部元素之上而触发了外层元素的onmouseout事件后,外层元素的onmouseover也会马上触发,所以我们只需要把外层元素的onmouseout事件需要执行的动作延迟很短的一段时间来运行,然后在onmouseover事件中再执行clearTimeout方法,这样就可以避免内部元素引起的事件干扰。

具体的执行过程请看下图(纵向的虚线表示时间):

这是个很巧妙的的方法,因为当onmouseout触发后,实质性的方法并没有马上执行,而是要等待一小段时间。如果在这段时间里马上又触发了 onmouseover事件,那么基本上就可以肯定onmouseout事件的触发是因为内部元素的干扰了,所以在onmouseover事件中使用 clearTimeout来阻止延时的方法执行。

二.contains

在onmouseover时先进行如下判断,结果为true时再执行方法体:

  1. 1 $("#popFormDiv").mouseover(function () {
    2 var s = event.fromElement || event.relatedTarget;
    3 if (!this.contains(s)) { $(this).show("slow"); }
    4 });

在onmouseout时先进行如下判断,结果为true时再执行方法体:

  1. $("#popFormDiv").mouseout(function () {
    var s = event.toElement || event.relatedTarget;
    if (!this.contains(s)) { $(this).hide("slow"); }
    });

下面来解释一下上面两行代码的含义:

IE中,所有的HTML元素都有一个contains方法,它的作用是判断当前元素内部是否包含指定的元素。我们利用这个方法来判断外层元素的事件是不是因为内部元素而被触发,如果内部元素导致了不需要的事件被触发,那我们就忽略这个事件。

event.fromElement指向触发onmouseover和onmouseout事件时鼠标离开的元素;event.toElement指向触发onmouseover和onmouseout事件时鼠标进入的元素。

那么上面两行代码的含义就分别是:

○ 当触发onmouseover事件时,判断鼠标离开的元素是否是当前元素的内部元素,如果是,忽略此事件;

○ 当触发onmouseout事件时,判断鼠标进入的元素是否是当前元素的内部元素,如果是,忽略此事件;

这样,内部元素就不会干扰外层元素的onmouseover和onmouseout事件了。

问题又来了,非IE的浏览器并不支持contains函数,不过既然我们已经知道了contains函数的作用,就可以自行添加如下的代码来为非IE浏览器增加contains支持:

  1. 1 if (typeof (HTMLElement) != "undefined") {
    2
    3 HTMLElement.prototype.contains = function (obj) {
    4
    5 while (obj != null && typeof (obj.tagName) != "undefined") {
    6
    7 if (obj == this)
    8
    9 return true;
    10
    11 obj = obj.parentNode;
    12
    13 }
    14
    15 return false;
    16
    17 };
    18
    19 }
  2.  
  3. 转自:http://www.haogongju.net/art/1085769
  4.  
  5. 更多:http://dm.5212m.com/a/JavaScript/2011/3/201131714147.shtml

relatedTarget, fromElement, toElement的更多相关文章

  1. 转载请注明出处: https://github.com/qiu-deqing/FE-interview

    转载请注明出处: https://github.com/qiu-deqing/FE-interview Table of Contents generated with DocToc FE-inter ...

  2. 【ToolKit】轻量级JS库

    优点: 丢弃了一些不常用的方法(jQuery.fn):slideUp.fadeIn.animate等: 新增获取子节点的方法(ToolKit.fn):firstChild,lastChild等: 新增 ...

  3. 深入理解DOM事件类型系列第一篇——鼠标事件

    × 目录 [1]类型 [2]顺序 [3]坐标位置[4]修改键[5]相关元素[6]鼠标按键[7]滚轮事件[8]移动设备 前面的话 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备.本文 ...

  4. jQuery-1.9.1源码分析系列(十) 事件系统——事件包装

    首先需要明白,浏览器的原生事件是只读的,限制了jQuery对他的操作.举个简单的例子就能明白为什么jQuery非要构造一个新的事件对象. 在委托处理中,a节点委托b节点在a被click的时候执行fn函 ...

  5. [JS]笔记14之事件委托

    -->什么是事件委托-->事件委托原理-->事件委托优点-->事件源 / 目标源 一.什么是事件委托 通俗的讲,onclick,onmouseover,onmouseout等这 ...

  6. BOM与事件

    PPK谈JS学习笔记第二弹 JS的语言核心和DOM之间有一个过渡层,一般称为BOM,浏览器对象模型.是指JS的客户端实现,它不操作DOM,又不是JS的语言核心,它的主要功能是管理浏览器窗口,每个窗口都 ...

  7. jQuery源代码学习之九—jQuery事件模块

    jQuery事件系统并没有将事件坚挺函数直接绑定在DOM元素上,而是基于事件缓存模块来管理监听函数的. 二.jQuery事件模块的代码结构 //定义了一些正则 // // //jQuery事件对象 j ...

  8. web面试题大全

    $HTML, HTTP,web综合问题 常见排序算法的时间复杂度,空间复杂度 前端需要注意哪些SEO web开发中会话跟踪的方法有哪些 <img>的title和alt有什么区别 docty ...

  9. JS小记

    好记性不如烂笔头. 1.document.ElementFromPoint:根据坐标获得元素 2.有时候要操作DOM页面,但是得不到预期结果,很可能是因为页面还没加载完成,在console控制台可以看 ...

随机推荐

  1. hyper中安装wdOS-1.0-x86_64(wdlinux)遇到的网卡问题

    11/23 0:30 by vmaxhyper中安装wdOS-1.0-x86_64(wdlinux) 日志: 遇到的问题: 1.装完找不到网卡eth0,只有一只loopback的Lo. 原因:cent ...

  2. jQuery图片懒加载lazyload插件

    http://www.neoease.com/lazy-load-jquery-plugin-delay-load-image/ js 模板引擎

  3. python针对于mysql的增删改查

    无论是BS还是CS得项目,没有数据库是不行的. 本文是对python对mysql的操作的总结.适合有一定基础的开发者,最好是按部就班学习的人阅读.因为我认为人生不能永远都是从零开始,那简直就是灾难. ...

  4. ACboy needs your help again!--hdu1702

    ACboy needs your help again! Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  5. Android小记之--ClickableSpan

    在给TextView设置超链接时,要想ClickableSpan的onClick事件响应,还必须同时设置tv.setMovementMethod(LinkMovementMethod.getInsta ...

  6. App_Code

    App_Code,文件夹是·NET平台下.在创建网站时,系统为类自动放的位置.它位于Web应用程序根目录下,其存储所有应当作为应用程序的一部分动态编译的类文件.这些类文件自 动链接到应用程序,而不需要 ...

  7. 保存mysql用户的登录信息到~.my.cnf文件;用于方便登录操作。

    原理说明: 在用户调用mysql 这个客户端程序去登录目标服务器时,mysql客户端程序会从本地读取配置文件信息,它要去读的配置文件包括 /etc/my.cnf /etc/mysql/my.cnf ~ ...

  8. Oracle EBS-SQL (OM-1):查询订单发货明细.sql

    select mtrh.request_number                  发货单号,       mmt.transaction_date                  发货时间,  ...

  9. jQuery的touchstart,touchmove,touchend的获取位置

    $('#webchat_scroller').on('touchstart',function(e) { var touch = e.originalEvent.targetTouches[0]; v ...

  10. SQLServer查看和解决死锁的方法

    http://luohonghong.blog.163.com/blog/static/78312058201142411533316/ SQLServer查看和解决死锁的方法 2011-05-24 ...