javascript中mouseover、mouseout使用详解


Posted in Javascript onJuly 19, 2015

本文并没有像标题说的那样,真正阻止事件元素的子元素冒泡...

只是在子元素冒泡到事件元素处时进行了一个判断,判断是否要触发事件,哦...不对 应该是是否要运行事件函数中的相关操作...

首先你可以猛戳这里: 问题的出现

 注: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 )

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

Javascript 相关文章推荐
一个奇葩的最短的 IE 版本判断JS脚本
May 28 Javascript
JS中自定义定时器让它在某一时刻执行
Sep 02 Javascript
jquery中push()的用法(数组添加元素)
Nov 25 Javascript
jQuery实现锚点scoll效果实例分析
Mar 10 Javascript
分离与继承的思想实现图片上传后的预览功能:ImageUploadView
Apr 07 Javascript
javascript显示倒计时控制按钮的简单实现
Jun 07 Javascript
jQuery的Read()方法代替原生JS详解
Nov 08 Javascript
浅谈vue的iview列表table render函数设置DOM属性值的方法
Sep 30 Javascript
JS的函数调用栈stack size的计算方法
Jun 24 Javascript
在vue中使用echarts图表实例代码详解
Oct 22 Javascript
JavaScript的console命令使用实例
Dec 03 Javascript
vue 组件基础知识总结
Jan 26 Vue.js
javascript实现的简单计时器
Jul 19 #Javascript
javascript中setInterval的用法
Jul 19 #Javascript
js中跨域方法原理详解
Jul 19 #Javascript
javascript获取网页宽高方法汇总
Jul 19 #Javascript
jQuery获取URL请求参数的方法
Jul 18 #Javascript
jQuery增加自定义函数的方法
Jul 18 #Javascript
jQuery插件简单实现方法
Jul 18 #Javascript
You might like
基于PHP CURL获取邮箱地址的详解
2013/06/03 PHP
php通过smtp邮件验证登陆的方法
2016/05/11 PHP
PHP扩展Swoole实现实时异步任务队列示例
2019/04/13 PHP
javascript判断用户浏览器插件安装情况的代码
2011/01/01 Javascript
快速排序 php与javascript的不同之处
2011/02/22 Javascript
结合JQ1.9通过js正则判断各种浏览器版本的方法
2013/12/30 Javascript
JavaScript严格模式详解
2017/01/16 Javascript
详解Vue中添加过渡效果
2017/03/20 Javascript
vue router路由嵌套不显示问题的解决方法
2017/06/17 Javascript
如何理解Vue的作用域插槽的实现原理
2017/08/19 Javascript
ES6 javascript中Class类继承用法实例详解
2017/10/30 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
Vue路由之JWT身份认证的实现方法
2019/08/26 Javascript
微信小程序定义和调用全局变量globalData的实现
2019/11/01 Javascript
[02:43]2014DOTA2国际邀请赛 官方Alliance战队纪录片
2014/07/14 DOTA
python list语法学习(带例子)
2013/11/01 Python
Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法
2016/04/23 Python
Python 搭建Web站点之Web服务器网关接口
2016/11/06 Python
Python中你应该知道的一些内置函数
2017/03/31 Python
python实现简单flappy bird
2018/12/24 Python
详解python中@的用法
2019/03/27 Python
python使用if语句实现一个猜拳游戏详解
2019/08/27 Python
python爬取天气数据的实例详解
2020/11/20 Python
Clarisonic美国官网:科莱丽声波洁面仪
2017/10/12 全球购物
Shopee印度尼西亚:东南亚与台湾市场最大电商平台
2018/06/17 全球购物
美国现代家具购物网站:LexMod
2019/01/09 全球购物
了解AppleTalk协议吗
2014/04/01 面试题
市政施工员自我鉴定
2014/01/15 职场文书
一夜的工作教学反思
2014/02/08 职场文书
大学共青团员个人自我评价
2014/04/16 职场文书
师德标兵先进事迹材料
2014/12/19 职场文书
2015年教师党员承诺书
2015/04/27 职场文书
西柏坡观后感
2015/06/08 职场文书
PostgreSQL存储过程实用脚本(二):创建函数入门
2021/04/05 PostgreSQL
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python
在CSS中使用when/else的方法
2022/01/18 HTML / CSS