冒泡和捕获 | 青训营

167 阅读2分钟

概念

1. 事件捕获

​ 捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)

2. 事件冒泡

冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发

事件流的传播

  • 事件:

    事件是发生在你正在编程的系统中的事情——当事件发生时,系统产生(或“触发”)某种信号,并提供一种机制,当事件发生时,可以自动采取某种行动(即运行一些代码)

JavaScript 事件分为三个阶段:

  • 捕获阶段:事件从父元素开始向目标元素传播,从Window对象开始传播
  • 目标阶段:该事件到达目标元素或开始该事件的元素
  • 冒泡阶段:这时与捕获阶段相反,事件向父元素传播,直到Window对象

Vue中事件修饰符

Vue中的事件修饰符如下:

  1. prevent:|阻止默认事件;
  2. stop:阻止事件冒泡;
  3. once:事件只触发一次;
  4. capture:使用事件的捕获模式;
  5. self:只有event.target是当前操作的元素是才触发事件;
  6. passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

这里用到stop和capture实现阻止冒泡和事件捕获,同时也可以在合适的位置使用e.preventDefault();e.stopPropagation();来阻止事件,可以自行尝试。

<!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>
    <script src="./js/vue.js" type="text/javascript"></script>
    <style>
        * {
            margin: 10px 0;
        }

        a {
            height: 50px;
            width: 100%;
        }

        .demo1 {
            height: 100px;
            width: 100%;
            background: blueviolet;
        }
    </style>
</head>

<body>
    <div id="root">
        <div class="demo1" @click="showInfo(event, 'demo1')">
            <button @click="showInfo1(event, 'button')">点我事件冒泡</button>
        </div>
        <div class="demo1" @click="showInfo(event, 'demo1')">
            <button @click.stop="showInfo1(event, 'button')">阻止事件冒泡</button>
        </div>
        <div class="demo1" @click.capture="showInfo(event, 'demo1')">
            <button @click="showInfo1(event, 'button')">事件捕获</button>
        </div>
    </div>
</body>
<script type="text/javascript">
    const vm = new Vue({
        el: "#root",
        methods: {
            showInfo(e, info) {
                // e.preventDefault();
                alert(info);
            },
            showInfo1(e, info) {
                // e.stopPropagation();
                alert(info);
            },
        }
    })
</script>

</html>

代码运行效果如图:

image.png

  • 点击第一个按钮时,会实现冒泡:

    点击后,按钮绑定点击事件,执行showInfo1实现alert弹窗;继续向上找,找到父级demo1中的点击事件,执行showInfo;再向上找,root,没有绑定点击事件,再到body,html,document,都没再有绑定的点击事件,冒泡过程结束。

  • 点击第二个按钮时,会阻止冒泡实现

  • 点击第三钮时,会进行事件捕获,即从外向内执行,先执行showInfo,再执行showInfo1