事件冒泡和事件捕获

390 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金

序言

事件流举例:你要去一个水桶里捞一个玩具,伸出一只手向下捞,在这称呼这个阶段为捕获阶段,然后捞到这个玩具,此时就称为处于目标阶段,再将该玩具捞起来,此时就称呼为冒泡阶段。

生动形象~,哈哈哈哈

DOM事件流

DOM事件流描述的是接收触发事件的顺序。

它分为三个阶段:

  1. 捕获阶段
  2. 目标阶段
  3. 冒泡阶段

示例(全文的html片段):

    <div id="s1">s1
        <div id="s2">s2
            <div id="s3">s3</div>
        </div>
    </div>
    <script>
        let s1 = document.getElementById("s1");
        let s2 = document.getElementById("s2");
        let s3 = document.getElementById("s3");
    </script>

事件流.png

事件冒泡

概念:事件从最里层的元素开始发生,一直向上传播,直到document对象

示例(js片段):

        s1.addEventListener("click", function (e) {
            console.log("s1 event1");
        }, false);

        s2.addEventListener("click", function (e) {
            console.log("s2 event1");
        }, false);

        s3.addEventListener("click", function (e) {
            console.log("s3 event1");
        }, false);

如果有小伙伴不了解addEventListener的参数的可以看一下EventTarget.addEventListener(),我这儿第三个参数为false(默认为false)是事件冒泡。

点击s1,控制台就打印结果: s1 event1

那么点击s2,s3呢?s2交由你们呐,当点击s3时

执行顺序

事件冒泡.png

事件捕获

概念:事件会从最外层开始发生,直到具体的元素

示例(js片段):

        s1.addEventListener("click", function (e) {
            console.log("s1 event2");
        }, true);

        s2.addEventListener("click", function (e) {
            console.log("s2 event2");
        }, true);

        s3.addEventListener("click", function (e) {
            console.log("s3 event2");
        }, true);

点击s3时,由于事件捕获机制,事件触发会从s1->s2->s3。

事件捕获.png

事件阻止

  • 阻止默认preventDefault():例如链接被点击会导航到其href指定的URL,这个就是默认行为。

示例:

    <a href="https://www.baidu.com/" id="atest">baidu</a>
    <script>
        let atest = document.getElementById("atest");
        atest.addEventListener("click", function (e) {
            e.preventDefault();
            console.log("阻止默认行为");
        }, false);
    </script>
  • 阻止传播stopPropagation():立即停止事件在下一层次中的传播,包括捕获和冒泡事件

示例1:

        s1.addEventListener("click", function (e) {
            console.log("s1 event1");
        }, false);

        s2.addEventListener("click", function (e) {
            e.stopPropagation();
            console.log("s2 event1");
        }, false);

        s3.addEventListener("click", function (e) {
            console.log("s3 event1");
        }, false);

点击s3,控制台打印

阻止传播示例1.png

示例2:

        s1.addEventListener("click", function (e) {
            console.log("s1 event2");
        }, true);

        s2.addEventListener("click", function (e) {
            e.stopPropagation();
            console.log("s2 event2");
        }, true);

        s2.addEventListener("click", function (e) {
            console.log("s2 event2 other");
        }, true);

        s3.addEventListener("click", function (e) {
            console.log("s3 event2");
        }, true);

点击s3,控制台打印

阻止传播示例2.png

  • 阻止传播强化版stopImmediatePropagation():除了它本身在的事件监听器,剩下的事件监听器都不会被调用。

示例:

        s1.addEventListener("click", function (e) {
            console.log("s1 event2");
        }, true);

        s2.addEventListener("click", function (e) {
            e.stopImmediatePropagation();
            console.log("s2 event2");
        }, true);

        s2.addEventListener("click", function (e) {
            console.log("s2 event2 other");
        }, true);

        s3.addEventListener("click", function (e) {
            console.log("s3 event2");
        }, true);

点击s3,控制台打印

阻止强化版示例1.png

结尾

不积小流,无以成江海