JavaScript事件的传播

JavaScript事件的传播

  • 当某个元素触发一个事件的时候,其父元素也会触发相同的事件,父元素的父元素 也会触发相同的事件
  • 子级标签绑定事件,父级标签也绑定相同类型的事件,
  • 子级标签触发事件,父级标签也会触发绑定的类型相同的事件
  • 这样的执行原理称为事件的传播 ,又叫:事件的冒泡或者冒泡事件


一、事件传播的方式

       在讲事件传播的方式之前,首先讲一下 目标 的概念:

              假设你点击了一个元素,那么这个元素就是事件的目标。

  • 在旧版本的浏览器中,事件的传播有 2种方式

    1、捕获

    • 从 父级 => 子级 执行程序
    • 也即: 从 外 至 内
    • 就是从 window 的事件处理函数开始,依次向内,直到事件 目标 的事件处理函数执行

    2、冒泡

    • 从 子级 => 父级 执行程序
    • 也即: 从 内 至 外
    • 就是从事件 目标 的事件处理函数开始,依次向外,直到 window 的事件处理函数触发。

  • 新版本浏览器 默认 都是以 冒泡方式 执行事件的传播

  • 给事件监听语法的第三个参数定义为 true,事件传播会按照捕获方式执行
    ​ 语法: 元素.addEventListener('事件类型', 事件处理函数, 冒泡还是捕获)
    ​                false:默认,冒泡
    ​                true:捕获



二、事件传播的阻止

       有些时候,我们并不想事件传播给父级的元素,这时就需要阻止事件的传播。

       事件传播的阻止需要考虑浏览器的兼容:

  • 标准浏览器
            事件对象.stopPropagation();

  • 低版本IE浏览器
           事件对象.cancelBubble = true;



三、事件传播案例

       接下来通过一个案例来更好的了解一下事件的传播

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 800px;
            height: 800px;
            background: pink;
            margin: 50px auto;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        h1 {
            width: 600px;
            height: 600px;
            background: orange;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        p {
            width: 400px;
            height: 400px;
            background: skyblue;
        }
    </style>
</head>

<body>
    <div>
        <h1>
            <p></p>
        </h1>
    </div>

    <script>
        var oDiv = document.querySelector('div');
        var oH1 = document.querySelector('h1');
        var oP = document.querySelector('p');
        var tBody = document.querySelector('body');
        var tHtml = document.querySelector('html');


        oDiv.addEventListener('click', function (e) {
            // 阻止事件的传播
            // e.stopPropagation();

            console.log('您点击的是div标签');
        })

        oH1.addEventListener('click', function (e) {
            // 阻止事件的传播
            // e.stopPropagation();

            console.log('您点击的是h1标签');
        })
       
        oP.addEventListener('click', function (e) {
             // 阻止事件的传播
            // e.stopPropagation();

            console.log('您点击的是p标签');
        })
        
          tBody.addEventListener('click', function (e) {
            console.log('您点击的是body标签');
        })
        
        tHtml.addEventListener('click', function (e) {
            console.log('您点击的是html标签');
        })
        
        document.addEventListener('click', function (e) {
            console.log('您点击的是document标签');
        })
        
        window.addEventListener('click', function (e) {
            console.log('您点击的是window标签');
        })
    </script>
</body>
</html>

1、上例中没有阻止事件的传播,点击<p>的时候,会依次触发<p>的点击事件、<h1>的点击事件、<div>的点击事件、<body>的点击事件、<html>的点击事件、document的点击事件、 window的点击事件。

       控制台会依次输出:
               您点击的是p标签
               您点击的是h1标签
               您点击的是div标签
               您点击的是body标签
               您点击的是html标签
               您点击的是document标签
               您点击的是window标签

  • 也就是说,页面上任何一个元素触发事件,都会从这个元素开始,一层一层的向父级传播事件,最终导致 window 的相同事件触发。前提是各层级元素得有注册相同的事件,不然不会触发。

2、在事件传播的过程中,有一些注意的点:

  • 只会传播同类事件

  • 只会从点击元素开始,按照 html 的结构,逐层向上触发父级元素的事件

  • 内部元素不管有没有该事件,只要上层元素有该事件,那么上层元素的事件就会被触发

    • 意思就是:如果把上例中<p>的点击事件代码删除,那么点击<p>的时候也会触发它的父级的点击事件,控制台会依次输出:

      • 您点击的是h1标签

      • 您点击的是div标签

      • 您点击的是body标签

      • 您点击的是html标签

      • 您点击的是document标签

      • 您点击的是window标签

3、最后思考一个问题

       事件会从自己开始,通过传播,直到 window 的所有相同事件都被触发;是因为我们点在自己身上,也逐层的点在了直至 window 的每一个元素身上,但是到底是先点在自己身上,还是先点在了window 身上呢?

先说结论:

  • 先点在自己身上,就是先执行自己的事件处理函数,逐层向上最后执行 window 的事件处理函数
  • 反之,则是先执行 window 的事件处理函数,逐层向下最后执行自己身上的事件处理函数

通过上例我们发现,点击<p>的时候,是先执行<p>的事件处理函数,再依次向上执行它父级的事件处理函数.
所以答案就是:先点在了自己身上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值