关于事件冒泡谨记

​ 下午学习Dom事件流,为了更深入的理解由于事件冒泡导致的mouseover和mouseenter的区别,进行了测试,特此记录。

1.Dom事件流

​ 所谓Dom事件流,指事件流描述 页面接收事件的顺序,也就是事件发生后的一定执行顺序。具体分为三个阶段:

|-捕获阶段:

|-目标阶段:

|-冒泡阶段:

用具体代码来解释上述阶段的含义:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dom事件流</title>
    <style>
        .fa {
            height: 100px;
            width: 100px;
            background-color: skyblue;
        }
        
        .son {
            height: 50px;
            width: 50px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <div class="fa">
        <div class="son"></div>
    </div>

    <script>
        var fa = document.querySelector('.fa');
        var son = document.querySelector('.son');
        
        fa.addEventListener('click', function() {
            console.log('冒泡 fa');
        }, false);
        fa.addEventListener('click', function() {
            console.log('捕获 fa');
        }, true);
        son.addEventListener('click', function() {
            console.log('冒泡 son');
        }, false);
        son.addEventListener('click', function() {
            console.log('捕获 son');
        }, true);
        document.addEventListener('click', function() {
            console.log('冒泡 document');
        }, false);
        document.addEventListener('click', function() {
            console.log('捕获 document');
        }, true);
    </script>
</body>

</html>

先看运行结果:

先点击蓝色区域,输出如下
在这里插入图片描述

再点击粉色区域,也就是子元素部分,输出如下

在这里插入图片描述

​ 也就是说,在该段代码中,点击了哪个元素,谁就是目标元素。

​ 从运行结果可以看出,事件流的总体执行顺序为先捕获,后冒泡。

捕获过程的先后顺序为:document->html->body->fa->son

冒泡过程为捕获的逆序:son->fa->body->html->document

​ 但是我们发现有一个特殊点,就是先输出冒泡son 后输出捕获son,因为对于目标元素来说,先捕获还是先冒泡完全要按照目标元素捕获和冒泡在代码中的顺序,谁在前就要先执行谁。

​ 那么如何从代码中区别事件冒泡还是捕获呢?事实上,不同点就在于addEventListener()的第三个参数,当第三个参数为false(可省略),事件冒泡。当第三个参数为true,事件捕获。

		//冒泡事件
		son.addEventListener('click', function() {
            console.log('冒泡 son');
        }, false);

		//捕获事件
        son.addEventListener('click', function() {
            console.log('捕获 son');
        }, true);

​ 所以回过头来再分析上面的代码:当点击子元素时,先输出捕获document->捕获父级div fa->接下来对于目标元素的子级div son因为在代码中冒泡事件在前,所以要先输出冒泡 son->后输出捕获son->目标元素之后整体开始捕获 即输出 冒泡fa->冒泡document

那么我们再来验证一下:

<style>
        .fa {
            height: 100px;
            width: 100px;
            background-color: skyblue;
        }
</style>
<body>
    <div class="fa"></div>
    <script>
        var fa = document.querySelector('.fa');
        fa.addEventListener('click', function() {
            console.log('冒泡 fa');
        }, false);
        fa.addEventListener('click', function() {
            console.log('捕获 fa');
        }, true);
        document.addEventListener('click', function() {
            console.log('冒泡 document');
        }, false);
        document.addEventListener('click', function() {
            console.log('捕获 document');
        }, true);
        //
    </script>
</body>

运行结果:在这里插入图片描述

<script>
        var fa = document.querySelector('.fa');

        fa.addEventListener('click', function() {
            console.log('捕获 fa');
        }, true);
        fa.addEventListener('click', function() {
            console.log('冒泡 fa');
        }, false);
        document.addEventListener('click', function() {
            console.log('冒泡 document');
        }, false);
        document.addEventListener('click', function() {
            console.log('捕获 document');
        }, true);
        //
    </script>

运行结果在这里插入图片描述

​ 需要注意的是,并不是所以的事件都有捕获和冒泡的

如:onfocus、onblur、onmouseenter、onmouseleaver

举例onmouseenter和onmouseover进一步测试对于有冒泡和没有冒泡事件的不同。代码如下:大家可以将代码粘贴到本地自行演示来体会

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .fa {
            height: 200px;
            width: 200px;
            background-color: pink;
        }
        
        .son {
            height: 100px;
            width: 100px;
            background-color: yellow;
        }
    </style>
</head>

<body>
    <div class="fa">
        <div class="son"></div>
    </div>
    <script>
        var fa = document.querySelector('.fa');
        var son = document.querySelector('.son');
        fa.addEventListener('mouseover', function() {
            console.log('mouseover');
        });
        fa.addEventListener('mouseenter', function() {
            console.log('mouseenter');
        });
    </script>
</body>
</html>

运行结果:

对于mouseover事件

​ |-鼠标移动到父元素粉色区域会输出“mouseover”。

​ |-鼠标移动到子元素粉色区域会输出“mouseover”,存在冒泡事件。

​ |-鼠标从父元素移动到子元素时,由于冒泡事件的存在,会输出“mouseover”。

​ |-当鼠标从子元素移动到父元素时,也会输出“mouseover”

对于mouseenter事件

​ |-当鼠标经过父元素会输出"mouseenter"

​ |-鼠标经过子元素也会输出"mouseenter",因为子盒子在父亲范围内,子元素占用父元素范围,所以鼠标经过子元素,相当于触发了父元素事件。

​ |-鼠标从父元素移动到子元素没有反应,不会输出"mouseenter"。因为对于mouseenter事件,不会冒泡传递,所以并不会触发父元素事件

​ |-鼠标从子元素移动到父元素没有反应,不会输出"mouseenter"。因为从整体来说鼠标一直都在父元素的范围内移动,并没有移动到其他地方,所以不会触发父元素的mouseenter事件。

总结mouseover和mouseenter的区别:

mouseover鼠标经过自身盒子会触发,经过子盒子还会触发,原因是mouseover发生冒泡事件

mouseenter只经过自己才会触发,mouseenter不会冒泡

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值