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.50 Alpha 与Opera9.00 Beta都不支持。其实Opera现在完全可以不要测试了,最新版的Opera都是webkit内核...

      谷歌低版本未测试...

当然这些老版本浏览器基本可以不用管了,所以这应该是最好的解决办法了:用mouseenter 与 mouseleave事件来替代mouseover 和 mouseout。

此二事件的实例戳这:mouseenter与mouseleave

注:jquery中也有mouseenter 与 mouseleave事件,兼容所有浏览器。

解决方法二:

上面那个方法在老版本的火狐与谷歌是不支持的,如果你希望得到最大范围的兼容,那可以继续往下看

我们利用var reltg = 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
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);
};

Li.onmouseout = function(e) {
  e = e||window.event;
  if (isMouseLeaveOrEnter(e,this)) {
    //运行相关操作
  };
}

此方法明显的缺点就是isMouseLeaveOrEnter中要遍历所有的父元素了,性能问题

解决方法三:

此方法与方法二其实思路是一样的,只是我们这里通过compareDocumentPosition/contains来判断li与reltg的包含关系,优化了方法二遍历所有父元素带来的性能问题。

直接看代码吧:

//判断node是否为parent的子元素
//if node == parent 也会返回true
function contains(parent, node) {
  if(parent.compareDocumentPosition){ //ff
    var _flag = parent.compareDocumentPosition(node);
    return (_flag == 20 || _flag == 0)? true : false;
  }else if(parent.contains){ //ie
    return parent.contains(node);
  }
};

Li.onmouseout = function(e) {
  e = e||window.event;
  var relatedEle = 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 )

以上所述就是本文的全部内容了,希望大家能够喜欢。

(0)

相关推荐

  • 实现onmouseover和onmouseout应用于RadioButtonList或CheckBoxList控件上

    一直想实现onmouseover和onmouseout应用于RadioButtonList或CheckBoxList控件上,今晚终于有时间实现它.此功能就是当鼠标经过时RadioButtonList或CheckBoxList每一个Item时,让Item有特效显示,离开时,恢复原样.可以看到效果: RadioButtonList效果: CheckBoxList效果: 这资实现数据,Insus.NET准备了五行(Five Phases) 创建一个对象[Five Phases]:FivePhases.

  • onmouseover和onmouseout的一些问题思考

    一个DIV层,当鼠标移进的时候会触发onmouseover,移出的时候会触发onmouseout.  很简单的逻辑,这也是我们想要的!但随之烦恼也就来了:onmouseover并不会只在移进时才触发,onmouseout也不会只在移出时才触发!鼠标在DIV里面移动时也会可能触发onmouseover或onmouseout.  在上图中,对于'A'来说:当鼠标进入'A'(路径'1′)时那么就会触发'A'的onmouseover事件:接着鼠标移动到'B'(路径'2′),此时'A'会触发onmouse

  • js ondocumentready onmouseover onclick onmouseout 样式

    复制代码 代码如下: <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="doInit()" /> <PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="doMouseover()" /> <PUBLIC:ATTACH EVENT="onclick" ONEVENT="doClick()&q

  • 经过绑定元素时会多次触发mouseover和mouseout事件

    javascript的mouseover和mouseout事件,在绑定元素内部有子元素的情况下, 经过绑定元素时会多次触发mouseover和mouseout事件. jquery解决办法: jquery的mouseenter和mouseleave方法已经修复了这个问题,可以直接用来替代mouseover和mouseout 不过有个mouseenter和mouseleave有个小问题是,让鼠标从文档外直接进入绑定事件的元素时,mouseenter不生效 暂时解决办法是,别让绑定事件的元素靠浏览器边

  • 基于mouseout和mouseover等类似事件的冒泡问题解决方法

    最近写点东西,比较闹心,一个弹出层,上边有其他元素,本意是鼠标离开弹出层时,执行一些动作,但在实际应用中,鼠标离开弹出层中的元素时,也会激活这些动作.试了各浏览器的停止事件冒泡的方法,均无效. 还是咱们javaeye里高人众多,在一个哥们博客中发现了如下代码: 复制代码 代码如下: function isMouseLeaveOrEnter(e, handler) {            if (e.type != 'mouseout' && e.type != 'mouseover')

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

    在IE里有onmouseleave和onmouseenter, 而对于要兼容各大浏览器的Web开发人员来说还是一件头疼的事. 虽然网上已经有针对Mozilla Firefox的一些计策,但代码量也是不容乐观的. 想寻求比较好的解决方案,于是就翻遍了国内的大小网站,终一无所获,不得不硬着头皮去读国外网站,结果是理想的,因为W3C里有relatedTarget,于是就有了下边的解决方案: 复制代码 代码如下: function isMouseLeaveOrEnter(e, handler) { if

  • 兼容ie和firefox的鼠标经过(onmouseover和onmouseout)实现--简短版

    前段时间一直找这个的简短实现  网上也有很多方法 昨天发现了这种方法 感觉是用代码最少的 呵呵 ie下支持css的js ff等支持:hover 就这样了 觉得好的就顶起来 无标题文档 #b_g_date tr{ event:expression(onmouseover = function(){this.style.backgroundColor='#E3FFC9'},onmouseout = function(){this.style.backgroundColor='#FFFFFF'});

  • JavaScript中BOM和DOM详解

    目录 BOM(浏览器对象模型) 1. window 获取浏览器c窗口尺寸 2. screen 获取电脑屏幕大小 3. window 开启关闭窗口 4. 浏览器事件 5. location 6. history 7. navigator 获取浏览器相关信息 8. 弹窗 DOM (文档对象模型) DOM 分类 DOM对象 Document文档对象 element文档对象 DOM事件操作 鼠标事件 键盘事件 触屏事件 特殊事件 表单事件 浏览器兼容处理 兼容性写法,封装工具 BOM(浏览器对象模型)

  • javascript中Array()数组函数详解

    在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只能存放同一类型或其子类型元素,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改. Array()是一个用来构建数组的内建构造器函数.数组主要由如下三种创建方式: array = new Array() array =

  • JavaScript中eval()函数用法详解

    eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行. 如果参数是一个表达式,eval() 函数将执行表达式.如果参数是Javascript语句,eval()将执行 Javascript 语句. 语法 复制代码 代码如下: eval(string) 参数 描述 string 必需.要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句. eval()函数用法详解: 此函数可能使用的频率并不是太高,但是在某些情况下具有很大的作用,下面就介绍一下eva

  • JavaScript中 ES6 generator数据类型详解

    1. generator简介 generator 是ES6引入的新的数据类型, 看上去像一个函数,除了使用return返回, yield可以返回多次. generator 由function* 定义, (注意*号), 2. 示例 函数无法保存状态, 有时需要全局变量来保存数字: 2.1 'use strict'; function next_id(){ var id = 1; while(id<100){ yield id; id++; } return id; } // 测试: var x,

  • javascript 中的继承实例详解

    javascript 中的继承实例详解 阅读目录 原型链继承 借用构造函数 组合继承 寄生组合式继承 后记 继承有两种方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法. 由于函数没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支持实现继承,而且实现继承主要依靠原型链来实现. 下面介绍几种js的继承: 原型链继承 原型链继承实现的本质是重写原型对象,代之以一个新类型的实例.代码如下: function SuperType() { this.pr

  • JavaScript中的函数式编程详解

    函数式编程 函数式编程是一种编程范式,是一种构建计算机程序结构和元素的风格,它把计算看作是对数学函数的评估,避免了状态的变化和数据的可变,与函数式编程相对的是命令式编程.我们有这样一个需求,给数组的每个数字加一: // 数组每个数字加一, 命令式编程 let arr = [1, 2, 3, 4]; let newArr = []; for(let i = 0; i < arr.length; i++){ newArr.push(arr[i] + 1); } console.log(newArr)

  • Javascript中window.name属性详解

    关于window下自带name的属性 不知道大家有没有发现这样一种情况 在控制台里直接输出未声明变量,正常情况应该是会报错的,而且声明未赋值的变量输出应该是undefined var a; //undefined b; //报错 但是偏偏就个别特例,就是name属性 其实window自身就带有name这个属性,在控制台输入window可以可以看到 打开 往下翻就可以找到 window.name直译过来是窗口名字,主要用于为超链接和表单设置目标(targets),什么意思呢,我们做个案例 建立两个

  • JavaScript中深拷贝与浅拷贝详解

    目录 1 浅拷贝概念 2 深拷贝概念 3 浅拷贝的实现方式 3.1 Object.assign() 3.2 Array.prototype.concat() 3.3 Array.prototype.slice() 3.4 直接赋值 4 深拷贝的实现方式 4.1 JSON.parse(JSON.stringify()) 4.2 函数库lodash 总结 1 浅拷贝概念 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的. 浅拷贝是创建一个新对象,该对象有着原始对象属性值的一份精确拷

  • javascript中json基础知识详解

    大致介绍 JSON(JavaScript Object Notation  JavaScript对象表示法),JSON是一种数据格式,不是一种编程语言.虽然它的名字中有JavaScript但是它却不属于JavaScript,就像Java和JavaScript的关系一样.而且,并不是只有JavaScript才使用它,毕竟 JSON 只是一种数据格式.很多编程语言都有针对 JSON 的解析器和序列化器. JSON是由Douglas Crockford在2001年提出,为了取代XML 语法 JSON的

  • JavaScript中的this使用详解

    其实this是一个老生常谈的问题了.关于this的文章非常多,其实我本以为自己早弄明白了它,不过昨天在做项目的过程中,还是出现了一丝疑惑,想到大概之前在JavaScript weekly里收藏待看的一篇详解this的文章(后有链接,也附上了稀土上的中文译文)和另一篇一位前辈推荐的文章,就把它们看了看,对this的认识确实提升了一些. JavaScript 中的'this'是动态的,它在函数运行时被确定而非在函数声明时被确定.所有的函数都可以调用'this',这无关于该函数是否属于某个对象.关于t

随机推荐