事件冒泡和事件捕获

在这里插入图片描述

由此可以知道
  1、一个完整的JS事件流是从window开始,最后回到window的一个过程
  2、事件流被分为三个阶段(15)捕获过程、(56)目标过程、(6~10)冒泡过程

示例:

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

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    #wrapDiv,
    #innerP,
    #textSpan {
      margin: 5px;
      padding: 5px;
      box-sizing: border-box;
      cursor: default;
    }

    #wrapDiv {
      width: 300px;
      height: 300px;
      border: indianred 3px solid;
    }

    #innerP {
      width: 200px;
      height: 200px;
      border: hotpink 3px solid;
    }

    #textSpan {
      display: block;
      width: 100px;
      height: 100px;
      border: orange 3px solid;
    }
  </style>
</head>

<body>
  <div id="wrapDiv">wrapDiv
    <p id="innerP">innerP
      <span id="textSpan">textSpan</span>
    </p>
  </div>
  <script>
    test_01 = () => {
      var wrapDiv = document.getElementById("wrapDiv");
      var innerP = document.getElementById("innerP");
      var textSpan = document.getElementById("textSpan");

      // 捕获阶段绑定事件
      window.addEventListener("click", function (e) {
        console.log("window 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      document.addEventListener("click", function (e) {
        console.log("document 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      document.documentElement.addEventListener("click", function (e) {
        console.log("documentElement 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      document.body.addEventListener("click", function (e) {
        console.log("body 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      wrapDiv.addEventListener("click", function (e) {
        console.log("wrapDiv 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      innerP.addEventListener("click", function (e) {
        console.log("innerP 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      textSpan.addEventListener("click", function (e) {
        console.log("textSpan 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      // 冒泡阶段绑定的事件
      window.addEventListener("click", function (e) {
        console.log("window 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      document.addEventListener("click", function (e) {
        console.log("document 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      document.documentElement.addEventListener("click", function (e) {
        console.log("documentElement 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      document.body.addEventListener("click", function (e) {
        console.log("body 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      wrapDiv.addEventListener("click", function (e) {
        console.log("wrapDiv 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      innerP.addEventListener("click", function (e) {
        console.log("innerP 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      textSpan.addEventListener("click", function (e) {
        console.log("textSpan 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);
    }
    // test_01();
    test_02 = () => {
      var wrapDiv = document.getElementById("wrapDiv");
      var innerP = document.getElementById("innerP");
      var textSpan = document.getElementById("textSpan");

      // 测试直接绑定的事件到底发生在哪个阶段


      wrapDiv.onclick = function () { //作用于非目标的事件,会遵守先捕获后冒泡的规则执行。且绑定的事件会在冒泡阶段执行,对比于冒泡事件,谁在前谁先执行。
        console.log("wrapDiv onclick 测试直接绑定的事件到底发生在哪个阶段")
      };

      wrapDiv.addEventListener("click", function (e) {
        console.log("wrapDiv 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      // 捕获阶段绑定事件
      window.addEventListener("click", function (e) {
        console.log("window 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      document.addEventListener("click", function (e) {
        console.log("document 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      document.documentElement.addEventListener("click", function (e) {
        console.log("documentElement 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      document.body.addEventListener("click", function (e) {
        console.log("body 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      wrapDiv.addEventListener("click", function (e) {
        console.log("wrapDiv 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      innerP.addEventListener("click", function (e) {
        console.log("innerP 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      textSpan.onclick = function () { //作用于目标的事件,不会遵守先捕获后冒泡的规则执行。该目标绑定的事件和冒泡事件,都会在该目标的捕获事件之前执行。且绑定的事件和冒泡事件,谁在前谁先执行。
        console.log("textSpan onclick")
      };

      textSpan.addEventListener("click", function () {
        console.log("textSpan 冒泡 在捕获之前绑定的")
      }, false);



      textSpan.addEventListener("click", function (e) {
        console.log("textSpan 捕获", e.target.nodeName, e.currentTarget.nodeName);
      }, true);

      // 冒泡阶段绑定的事件
      window.addEventListener("click", function (e) {
        console.log("window 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      document.addEventListener("click", function (e) {
        console.log("document 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      document.documentElement.addEventListener("click", function (e) {
        console.log("documentElement 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      document.body.addEventListener("click", function (e) {
        console.log("body 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);


      innerP.addEventListener("click", function (e) {
        console.log("innerP 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);

      textSpan.addEventListener("click", function (e) {
        console.log("textSpan 冒泡", e.target.nodeName, e.currentTarget.nodeName);
      }, false);
    }
    test_02();
  </script>
</body>

</html>

直接说结论:
作用于非目标的事件,会遵守先捕获后冒泡的规则执行。且绑定的事件会在冒泡阶段执行,对比于冒泡事件,谁在前谁先执行。
作用于目标的事件,不会遵守先捕获后冒泡的规则执行。该目标绑定的事件和冒泡事件,都会在该目标的捕获事件之前执行。且绑定的事件和冒泡事件,谁在前谁先执行。

来源 chenxj :https://www.cnblogs.com/Chen-XiaoJun/p/6210987.html

猜你喜欢

转载自blog.csdn.net/SilenceJude/article/details/83997368