JavaScript和JQuery的鼠标mouse事件冒泡处理


Posted in Javascript onJune 19, 2015

简单的鼠标移动事件:

进入

mouseenter:不冒泡

mouseover: 冒泡

不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件
只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件

移出

mouseleave: 不冒泡

mouseout:冒泡

不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件
只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件

我们通过一个案例观察下问题:

给一个嵌套的层级绑定mouseout事件,会发现mouseout事件与想象的不一样

<!DOCTYPE html><div class="out overout" style="width:40%;height:120px; margin:0 15px;background-color:#D6EDFC;float:left;" data-mce-style="width: 40%; height: 120px; margin: 0 15px; background-color: #d6edfc; float: left;"><p style="border:1px solid red" data-mce-style="border: 1px solid red;">外部子元素</p><div class="in overout" style="width:60%;background-color:#FFCC00;margin:10px auto;" data-mce-style="width: 60%; background-color: #ffcc00; margin: 10px auto;"><p style="border:1px solid red" data-mce-style="border: 1px solid red;">内部子元素</p><p id="inshow">0</p>

    </div><p id="outshow">0</p>

</div><script type="text/javascript">
    var i = 0;

    var k = 0;
    document.querySelectorAll('.out')[0].addEventListener('mouseout',function(e){

        document.querySelectorAll("#inshow")[0].textContent = (++i)

       e.stopPropagation();

    },false)
   document.querySelectorAll('.in')[0].addEventListener('mouseout',function(){

       document.querySelectorAll("#outshow")[0].textContent = (++k)

    },false)
</script>

我们发现一个问题mouseout事件:

1.无法阻止冒泡
2.在内部的子元素上也会触发

同样的问题还有mouseover事件,那么在stopPropagation方法失效的情况下我们要如何停止冒泡呢?

1.为了阻止mouseover和mouseout的反复触发,这里要用到event对象的一个属性relatedTarget,这个属性就是用来判断 mouseover和mouseout事件目标节点的相关节点的属性。简单的来说就是当触发mouseover事件时,relatedTarget属性代表的就是鼠标刚刚离开的那个节点,当触发mouseout事件时它代表的是鼠标移向的那个对象。由于MSIE不支持这个属性,不过它有代替的属性,分别是 fromElement和toElement。
2.有了这个属性,我们就能够清楚的知道我们的鼠标是从哪个对象移过来,又是要移动到哪里去了。这样我们就能够通过判断这个相关联的对象是否在我们要触发事件的对象的内部,或者是不是就是这个对象本身。通过这个判断我们就能够合理的选择是否真的要触发事件。
3.这里我们还用到了一个用于检查一个对象是否包含在另外一个对象中的方法,contains方法。MSIE和FireFox分别提供了检查的方法,这里封装了一个函数。

jQuery的处理也是如出一辙

jQuery.each({

        mouseenter: "mouseover",

        mouseleave: "mouseout",

        pointerenter: "pointerover",

        pointerleave: "pointerout"

    }, function(orig, fix) {

        jQuery.event.special[orig] = {

            delegateType: fix,

            bindType: fix,
            handle: function(event) {

                var ret,

                    target = this,

                    related = event.relatedTarget,

                    handleObj = event.handleObj;
                // For mousenter/leave call the handler if related is outside the target.

                // NB: No relatedTarget if the mouse left/entered the browser window

                if (!related || (related !== target && !jQuery.contains(target, related))) {

                    event.type = handleObj.origType;

                    ret = handleObj.handler.apply(this, arguments);

                    event.type = fix;

                }

                return ret;

            }

        };

    });
Javascript 相关文章推荐
jquery 实现二级/三级/多级联动菜单的思路及代码
Apr 08 Javascript
Jquery使用css方法改变样式实例
May 18 Javascript
JavaScript中reduce()方法的使用详解
Jun 09 Javascript
Javascript使用post方法提交数据实例
Aug 03 Javascript
jQuery实现简洁的导航菜单效果
Nov 23 Javascript
jQuery获取checkbox选中的值
Jan 28 Javascript
Bootstrap Table使用方法详解
Aug 01 Javascript
AngularJS使用ng-options指令实现下拉框
Aug 23 Javascript
webpack4.x打包过程详解
Jul 18 Javascript
微信小程序实现弹出菜单
Jul 19 Javascript
小程序点击图片实现png转jpg
Oct 22 Javascript
javascript遍历对象的五种方式实例代码
Oct 24 Javascript
TypeScript 中接口详解
Jun 19 #Javascript
TypeScript 学习笔记之基本类型
Jun 19 #Javascript
使用Chrome浏览器调试AngularJS应用的方法
Jun 18 #Javascript
使用AngularJS创建自定义的过滤器的方法
Jun 18 #Javascript
深入讲解AngularJS中的自定义指令的使用
Jun 18 #Javascript
3个可以改善用户体验的AngularJS指令介绍
Jun 18 #Javascript
在AngularJS应用中实现一些动画效果的代码
Jun 18 #Javascript
You might like
PHP file_get_contents设置超时处理方法
2013/09/30 PHP
php使用指定字符列表生成随机字符串的方法
2015/04/18 PHP
js资料prototype 属性
2007/03/13 Javascript
JavaScript让IE浏览器event对象符合W3C DOM标准
2009/11/24 Javascript
animate动画示例(泪奔的小孩)及stop和delay的使用
2013/05/06 Javascript
javascript去掉前后空格的实例
2013/11/07 Javascript
JavaScript是如何实现继承的(六种方式)
2016/03/31 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
jQuery实现调整表格单列顺序完整实例
2016/06/20 Javascript
JavaScript编写一个简易购物车功能
2016/09/17 Javascript
AngularJS表单和输入验证实例
2016/11/02 Javascript
关于Vue.js 2.0的Vuex 2.0 你需要更新的知识库
2016/11/30 Javascript
如何获取元素的最终background-color
2017/02/06 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
Vue用v-for给循环标签自身属性添加属性值的方法
2018/10/18 Javascript
浅谈vue3中effect与computed的亲密关系
2019/10/10 Javascript
JavaScript制作3D旋转相册
2020/08/02 Javascript
pydev使用wxpython找不到路径的解决方法
2013/02/10 Python
Python中方法链的使用方法
2016/02/23 Python
Python利用BeautifulSoup解析Html的方法示例
2017/07/30 Python
全面了解Nginx, WSGI, Flask之间的关系
2018/01/09 Python
Python socket模块实现的udp通信功能示例
2019/04/10 Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
2019/07/15 Python
TensorFlow实现简单的CNN的方法
2019/07/18 Python
检测tensorflow是否使用gpu进行计算的方式
2020/02/03 Python
获取CSDN文章内容并转换为markdown文本的python
2020/09/06 Python
通用的Django注册功能模块实现方法
2021/02/05 Python
Marlies Dekkers内衣法国官方网上商店:国际知名的荷兰内衣品牌
2019/03/18 全球购物
求职信模版
2013/11/30 职场文书
实习协议书范本
2014/04/22 职场文书
幼儿园门卫岗位职责范本
2014/07/02 职场文书
员工表扬信怎么写
2015/05/05 职场文书
收入证明申请书
2015/06/12 职场文书
如何利用js在两个html窗口间通信
2021/04/27 Javascript
Python 循环读取数据内存不足的解决方案
2021/05/25 Python
动画「进击的巨人」第86话播出感谢绘公开
2022/03/21 日漫