JavaScript事件冒泡, 事件委托

事件冒泡

事件冒泡: 子元素上触发事件时, 会触发父元素同样的事件

触发事件的 `当事人` : 事件参数中的 target 属性 -- 存储的是当事元素

代码片段:

<!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>事件冒泡</title>
    <style>
        #red{
            background-color: red;
            width: 500px;
            height: 500px;
        }
        #green{
            background-color: green;
            width: 400px;
            height: 400px;
        }
        #blue{
            background-color: blue;
            width: 300px;
            height: 300px;
        }
    </style>
</head>
<body>
    <div id="red">
        <div id="green">
            <div id="blue"></div>
        </div>
    </div>

    <script>
        red.onclick = function(e){
            console.log('red click!');
            console.log('触发本次事件的当事元素:', e.target);
        }

        green.onclick = function(e){
            console.log('green click!');
            console.log('触发本次事件的当事元素:', e.target);
        }

        blue.onclick = function(e){
            console.log('blue click!');
            console.log('触发本次事件的当事元素:', e.target);
        }
    </script>
</body>
</html>

样式就是这样的一个样式, 三个盒子嵌套, 当我们点击蓝色盒子时, 下面绿色盒子和红色盒子都会被触发的 

可以看到, 点击蓝色盒子, 其它两个都会被触发, 当我们点击绿色盒子, 而红色盒子就会触发

 

那该怎么解决呢? DOM提供了这样的一个 stopPropagation 方法

停止冒泡: 父元素不会收到此次事件的通知

stop: 停止   propagation: 传播

把 stopPropagation 这个方法添加到蓝色盒子的脚本里面, 就不会影响其它两个啦

扫描二维码关注公众号,回复: 16504970 查看本文章
blue.onclick = function (e) {
    console.log("blue click!");
    console.log("触发本次事件的当事元素:", e.target);
    e.stopPropagation();
};

都是触发自身的元素

事件委托

冒泡的应用场景: 委托

自己的事情 让别人帮忙处理; 此处 - 子元素的事情, 让父元素帮忙处理

然而最经典的例子就是 ul 和 li 了

下面来看这样的一个例子

点击谁, 谁高亮显示, 平常我们都是用forEach遍历 li 来显示的, 这里我们就来用事件委托的方式绑定 ul 来实现这样的效果, 先来准备 html 和 css 代码

<!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>事件委托</title>
    <style>
      ul {
        display: flex;
        margin: 0;
        padding: 0;
        list-style: none;
        border: 1px solid gray;
      }

      li {
        padding: 10px 20px;
        background-color: #eee;
        margin: 5px;
        cursor: pointer;
      }
      .active {
        background-color: orange;
        color: white;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>TheShy</li>
      <li>Ning</li>
      <li>Rookie</li>
      <li>JackeyLove</li>
      <li>BaoLan</li>
    </ul>
  </body>
</html>

 这就是简简单单的 基础代码 这里就不必过多阐述了,  平常我们都是用下方这种方法来实现的

<script>
    const lis = document.querySelectorAll('ul>li')
    lis.forEach(li => li.onclick = function(){
        lis.forEach(li => li.classList.remove('active'))
        this.classList.add('active')
    })
</script>

 然后这种方式的缺点就是: 需要为每个 li 绑定单独的方法, 然而来看下方的委托方式

<script>
    const ul = document.querySelector("ul");
      ul.onclick = function (e) {
        console.log("ul click!");
        console.log("当事元素:", e.target);
        console.dir(e.target);

        if (e.target.localName == "li") {
          e.target.classList.add("active");
        }
      };
</script>

这里呢首先把 li 的父元素 ul 找到, 然后绑定一个点击事件, 通过 冒泡的 方式接收事件的 `当事人`, 这里就是说的当事元素, 然后通过打印可以点击一下, 查找一下我们所需要的方式都有哪些

通过查找我们看到, 一共呢找到了三种, 一个是 localName 与 nodeName 与 tagName, 这三个方法, 这三个方法用哪个都可以, 我这边用的是localName, 因为平时都是用这个方法, 换其它的还有点不自在, 最终通过if判断来执行点击谁, 把 active 添加到谁身上就可以了;

好了, 今天就到这里了 O(∩_∩)O

猜你喜欢

转载自blog.csdn.net/m0_67212141/article/details/128307513