问题:当鼠标移动到元素上,多次触发mouseover,mouseout事件。

(注,该问题是在实现鼠标移动到一起菜单,滑动弹出二级时碰到的;因为鼠标移动到二级菜单时,动画再次触发,才意识到该问题;之前因为使用的是:hover伪类实现的显示二级菜单,并且没有加入动画,所以并没有发现该问题。)

问题原因分析:事件的冒泡机制,当子元素上发生相应事件时,会触发父级元素的该事件。如A元素包含B元素,在A,B元素上分别添加mouseover,mouseout监听事件,当鼠标移到A上,但不在B上时,触发A的mouseover,同时对应的event.eventPhase为2即目标阶段;当鼠标继续移入B元素中时,这时触发A事件的mouseout,event.eventPhase为3,即冒泡阶段,同时触发B事件的mouseover,event.eventPhase为2,即目标阶段。

解决方法:检测事件的相关元素(relatedTarget,对于mouseover来说:relatedTarget是鼠标进入元素前,所离开的元素;对于mouseout,relatedTarget是鼠标离开元素后,所进入的元素)是被绑定元素的子元素与否。(或者利用jQuery的mouseenter,mouseleave事件,因为jquery已经将该事件封装)

function contains(parentNode, childNode) {if (parentNode.contains) {return parentNode != childNode && parentNode.contains(childNode);} else {return !!(parentNode.compareDocumentPosition(childNode) & 16);}
}

该函数是判断两个节点的关系,它考虑到IE与其他浏览器的兼容性,[dom].contains([dom])方法是IE浏览器的方法([dom]表示文档流中的节点),[A].compareDocumentPosition([B])是DOM3中的方法,下面是不同位置关系对应的返回结果。

Bits          Number        Meaning
000000         0              元素一致
000001         1              节点在不同的文档(或者一个在文档之外)
000010         2              节点 B 在节点 A 之前
000100         4              节点 A 在节点 B 之前
001000         8              节点 B 包含节点 A
010000         16             节点 A 包含节点 B
100000         32             浏览器的私有使用

接下来是判断事件相关元素与目标元素之间的关系,只有当触发事件的相关元素不是目标元素的后继节点,checkHover()函数才返回true.

function checkHover(e,target){if (getEvent(e).type=="mouseover")  {return !contains(target,getEvent(e).relatedTarget||getEvent(e).fromElement) && !((getEvent(e).relatedTarget||getEvent(e).fromElement)===target);} else {return !contains(target,getEvent(e).relatedTarget||getEvent(e).toElement) && !((getEvent(e).relatedTarget||getEvent(e).toElement)===target);}
}

getEvent是为了兼容IE浏览器;checkHover函数中之所以添加一个if判断是因为IE下mouseover和mouseout的相关元素分别对应的是fromElement,toElement,因此分别处理,当是其他事件时,这两个属性在IE下为null。而FF和chrome浏览器中的相关元素都是relatedTarget,mouseover中relatedTarget是鼠标移到目标元素时所离开的那个元素,mouseout中relatedTarget是鼠标离开目标元素时要进入的元素,对于其他事件该属性无用。

最后是函数的调用。

myElement.οnmοuseοver=function(e){if(checkHover(e,this)){do someting...}
}

附加:

1)event还有两个对象currentTarget,target;currentTarget是当前响应事件的对象,target是最初触发该事件的对象;

2)阻止事件的冒泡为event.stopPropagation();

3)阻止默认行为为event.perventDefault();

4)在处理函数中最后写上return false;即阻止冒泡又阻止默认操作。

5)事件分为3个阶段:捕捉阶段,eventPhase为1;目标阶段,eventPhase为2;冒泡阶段,eventPhase为3。

下面为测试时,监控程序的代码

var count=0;
$(this).bind('mouseover',function(e){console.log(++count+' mouseover: '+e.target.className+" "+e.eventPhase);...}).bind('mouseout',function(e){console.log(++count+' mouseout: '+e.target.className+" "+e.eventPhase);...
})

转载于:https://www.cnblogs.com/hugh2006/p/3637131.html

js mouseover mouseout 多次触发相关推荐

  1. 鼠标悬浮效果:css:hover;js:mouseover,mouseout

    目录 一.css样式实现 二.js实现 一.css样式实现 1.xxx:hover 只能生成css可以控制的样式效果 <style>div:hover{color:red;} </s ...

  2. js mouseover/mouseout不停地循环

    情形: 我要在鼠标经过tbody中的tr时,会产生事件. 这个事件是给tr中的td写内容,内容是带标签的,如: <p>abc</p>. 结果发现,当鼠标经过abc的时候会不停地 ...

  3. js当中mouseover和mouseout多次触发(非冒泡)

    JS当中,mouseover和mouseout多次触发事件,不光是冒泡会产生,就是不冒泡,在一定条件下 ,也会产生多次触发事件: 例如下面的结构的情况下,我在class="ceng_up f ...

  4. html js不触发_图文详解鼠标事件CSS:hover和JS:mouseover的区别

    在工作中为了使页面更具有吸引力,前端开发人员经常会在页面中加上鼠标移入和移出的效果.鼠标移入移出的设置,一般有两种方法,一种是单纯用CSS中的hover伪类,另一种可以用JS 中的DOM事件,即onm ...

  5. JavaScript中mouseover和mouseout多次触发解决办法

    问题描述 我希望当鼠标移动到id1上的时候,id2显示,当鼠标离开id1的时候,id2不显示.问题如下: 1.当鼠标从id1上移动到id2上的时候,id由有显示变为不显示,然后变为显示 2.当鼠标从i ...

  6. mouseover和mouseout多次触发解决方法(兼容ie和firefox)(转)

    在用到mouseover和mouseout事件来作为事件触发的条件,但是如果我们用做触发的元素内部有其他的元素的时候当鼠标移上的时候会反复的触发mouseover和mouseout事件,如导致菜单闪烁 ...

  7. js 鼠标事件总结 mouseover/mouseout 与mouseenter/mouseleave 傻傻分不清楚?

    1. 鼠标事件 mouseenter mouseleave (一对事件 鼠标的进入和离开) 不支持冒泡 mouseenter:鼠标从元素外部移到元素内部时触发. mouseleave:鼠标从元素内部移 ...

  8. mouseOver/mouseOut 与 rollOver/rollOut的区别

    一直在做有关鼠标移动都是用mouseOver,mouseOut. 但是最近做一個项目的时候用mouseOver,mouseOut出问题.后来网络上找了一下关于mouseOver,mouseOut的研究 ...

  9. 转载:mouseOver/mouseOut 与 rollOver/rollOut的区别

    一直在做有关鼠标移动都是用mouseOver,mouseOut. 但是最近做一個项目的时候用mouseOver,mouseOut出问题.后来网络上找了一下关于mouseOver,mouseOut的研究 ...

  10. java mouseenter_关于事件mouseover ,mouseout ,mouseenter,mouseleave的区别

    最近在做的在线考试和课程商城都遇到这样的问题:就是鼠标滑过的时候出现一个层,当鼠标滑到当前层的话mouseover和mouseout在低版本的浏览器会出现闪动的现象,解决这个现象的办法有许多,不过我觉 ...

最新文章

  1. 布隆过滤器+布隆过滤器(Bloom Filter)详解
  2. 职业-把工作当作职业 or 事业?
  3. java中间缓存变量机制_Java中间缓存变量机制
  4. 深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
  5. 2.sort 排序命令讲解
  6. 关于wifi的HW hdr error:len/check错误解决方法
  7. 本地浏览器缓存sessionStorage(临时存储) localStorage(长期存储)的使用
  8. java递归实现多级菜单栏_vue+ java 实现多级菜单递归效果
  9. Netty学习总结(6)——Netty使用注意事项
  10. CentOS查看CPU,内存,位数行等信息命令
  11. HDU 1034 - Candy Sharing Game
  12. 图解算法:八大排序算法
  13. 谢尔宾斯基三角形——python递归
  14. Python实现伽马矫正
  15. iPhone苹果手机怎么定位追踪另外一个苹果iPhone手机的位置?
  16. 【思维方法】之第一性原理
  17. MySQL_Windows 下重启MySQL服务
  18. 记我的第一次腾讯游戏策划面试
  19. 是计算机程序设计语言的是,计算机设计语言
  20. suparc服务器没信号,SupARC对战平台新手上手教程

热门文章

  1. IP与以太网的包收发操作
  2. 查看 chrome 浏览器中的 Headers
  3. Ogre3D的GOOF的场景编辑器截图
  4. 文本处理命令系列——cut
  5. IOS 开展 分别制定了iphone 和 ipad 好? 或开发一个 Universal好?
  6. Lua 脚本汇编-入门到精通
  7. XP的常见蓝屏代码和解决方案
  8. POJ 1151 Atlantis 矩形面积求交/线段树扫描线
  9. SQL server脚本语句积累
  10. Python PIL 图像缩小、拼接