JavaScript 事件冒泡与捕获机制 --- 带动态图理解

 (1).事件捕获

从根元素往上传递  --- ---(由外到内)

(2).事件冒泡

从元素传递到它的根源素  --- --- (由内到外)

代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <!-- js中方法需要加() 如captrueMode()  -->

  <body>
    <div class="buttonBox">
      <button class="captrue" onclick="captrueMode('捕获模式')">
        捕获模式
      </button>
      <button class="bubbling" onclick="bubblingMode('冒泡模式')">
        冒泡模式
      </button>
      <div>当前模式为:(<span id="activeShow"></span>)</div>
    </div>
    <div id="six">
      6
      <div id="five">
        5
        <div id="four">
          4
          <div id="three">
            3
            <div id="two">
              2
              <div id="one">1</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
  <script>
    // 获取元素
    const elementArr = Array.from(
      document.querySelectorAll("#one, #two, #three, #four, #five, #six")
    );

    let modeFlag = false; // 默认 -- 冒泡模式
    // 改变模式提示文字方法
    const updateText = (text) => {
      return (document.getElementById("activeShow").innerText = text);
    };

    // ! 模式效果操作函数封装
    const directionHandle = function (event) {
      operateHandle(event, this);
    };
    // 元素添加监听控制事件方法封装
    const addEventIsElement = function () {
      elementArr.forEach((item) =>
        item.addEventListener("click", directionHandle, modeFlag)
      );
    };
    // 元素删除监听控制事件方法封装
    const removeEventIsElement = function () {
      elementArr.forEach((item) =>
        item.removeEventListener("click", directionHandle, modeFlag)
      );
    };
    // 切换为捕获模式
    function captrueMode(mode) {
      removeEventIsElement();
      (modeFlag = true), updateText(mode);
      addEventIsElement();
    }

    // 切换为冒泡模式
    function bubblingMode(mode) {
      removeEventIsElement();
      (modeFlag = false), updateText(mode);
      addEventIsElement();
    }
    bubblingMode("冒泡模式"); // 默认切换为冒泡模式
    let showTime = 0;
    let cancelShowTime = 1000;

    // !! 类名绑定操作函数 --  x
    const updateClass = (thisDirection, isAccNumber = false) => {
      if (isAccNumber) {
        (showTime += 1000), (cancelShowTime += 1000);
      }
      setTimeout(() => {
        thisDirection.classList.add("activeColor");
      }, showTime); // 2s
      setTimeout(() => {
        thisDirection.classList.remove("activeColor");
      }, cancelShowTime);
    };

    const resetTime = function () {
      showTime = 0;
      cancelShowTime = 1000;
    };
    // !! 封装操作函数 --  x
    const operateHandle = (event, thisDirection) => {
      if (modeFlag) {
        if (thisDirection.id === "six") {
          resetTime();
          updateClass(thisDirection);
        } else {
          updateClass(thisDirection, true);
        }
      } else {
        if (event.srcElement.id === thisDirection.id) {
          resetTime();
          updateClass(thisDirection);
        } else {
          updateClass(thisDirection, true);
        }
      }
    };
  </script>
</html>
<style lang="css">
  #six {
    width: 1200px;
    height: 300px;
    border: 1px solid #000;
    text-align: center;
    margin: auto;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -110%);
    background-color: #fff;
  }

  #five {
    width: 1000px;
    height: 250px;
    border: 1px solid #000;
    margin: auto;
    background-color: #fff;
  }

  #four {
    width: 800px;
    height: 200px;
    border: 1px solid #000;
    margin: auto;
    background-color: #fff;
  }

  #three {
    width: 600px;
    height: 150px;
    border: 1px solid #000;
    margin: auto;
    background-color: #fff;
  }

  #two {
    width: 400px;
    height: 100px;
    border: 1px solid #000;
    margin: auto;
    background-color: #fff;
  }

  #one {
    width: 200px;
    height: 50px;
    border: 1px solid #000;
    margin: auto;
    background-color: #fff;
  }

  .activeColor {
    background-color: red !important;
  }

  .captrue {
    width: 120px;
    height: 36px;
  }

  .buttonBox {
    width: 1200px;
    margin: auto;
  }

  .bubbling {
    width: 120px;
    height: 36px;
  }
</style>

(3). 事件委托(利用事件冒泡原理,把事件委托给父元素实现,给父元素添加点击事件,可在参数e.target中获取到点击的元素,实现此行的操作)

事件委托:在需要的时候把事件交给别的元素来做 --- ---

优点 :(1) 减少内存消耗 ---- ---- 不用在每个标签上添加事件,只需获取父元素下的元素,绑定事件即可完成全部操作。

            (2) 具有动态绑定的效果 ---- ---- 在获取全部元素的条件下,不管增加或者减少的情况下都是一样的

 示例:

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

<head>
    <meta charset="UTF-8" />
    <title>JavaScript</title>
</head>

<body>
    <ul id="list" style="width: 100px; margin: 0; float: left;">
        <li>1<button id="rowDel">删除此条</button><button id="rowEdit">修改此条</button></li>
        <li>2<button id="rowDel">删除此条</button><button id="rowEdit">修改此条</button></li>
    </ul>
    <button onclick="addli()">添加一个 li</button>
    <script>
        let list = document.getElementById("list");

        function addli() {
            let conentElement = document.createElement("li");
            conentElement.innerHTML =
                `${ list.childElementCount + 1 }<button id="rowDel">删除此条</button><button id="rowEdit">修改此条</button>`;
            list.appendChild(conentElement);
        };
        
        list.onclick = function (e) {
            debugger
            let activeElement = e.target;
            activeElement.id == "rowDel" ? list.removeChild(activeElement.parentNode) : activeElement
                .parentNode.innerHTML = "<div>修改中</div>"
        }
    </script>
</body>
<style>
    list {
        display: block;
    }

    button {
        float: right;
    }

    li {
        width: 300px;
        display: flex;
    }
</style>

</html>
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值