结构

<style>
    .father {
        width: 500px;
        height: 500px;
        background: black;
    }
 
    .son {
        width: 250px;
        height: 250px;
        background: yellow;
    }
</style>
 
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

事件冒泡

  <script>
        let father = document.querySelector('.father')
        let son = document.querySelector('.son')
        father.addEventListener('click',()=>{
            console.log('father');
        })
        son.addEventListener('click',(e)=>{
            console.log('son');
        })
    </script>

 父盒子和子盒子是嵌套关系  当点击子盒子和父盒子共同的部分时,就会产生一种现象 叫作事件冒泡,分别给父子盒子注册事件后 打印输出结果

发现点击子盒子时 父盒子的事件也触发了,为什么叫冒泡呢  因为子盒子在父盒子里面 是从里向外 冒出来的,所以称为冒泡。

阻止冒泡

通过事件参数e.stopPropagation方法达到阻止冒泡的效果

 son.addEventListener('click',(e)=>{
            e.stopPropagation()
            console.log('son');
        })

如果是vue

<button @click.stop="hClick"></button>

 

二、事件捕获

事件捕获 只能通过addEventListener 的第三个参数去实现,如果不写则为false,如果为ture则是开启了事件捕获, 通过下面的代码继续点击相同的部分。

        let father = document.querySelector('.father')
        let son = document.querySelector('.son')
        father.addEventListener('click',()=>{
            console.log('father');
        },true)
        son.addEventListener('click',(e)=>{
            console.log('son');
        })

 捕获正好和冒泡相反,是从外向里传递事件,注意onclick并不能达到事件捕获的效果 ,只有addEventListener 的第三个参数手动去实现。

三、事件委托


  事件委托本质上发生在事件中,委托事情交给被人去做,达到自己做的一个目的,如果一个元素是动态创建的且要给该元素注册事件,那么必须使用委托,给ul注册点击事件 e.target拿到的是 每个li

<body>
    <ul>
        <li>第1个li</li>
        <li>第2个li</li>
        <li>第3个li</li>
        <li>第4个li</li>
    </ul>
    <script>
 
        // 事件捕获
        let ul = document.querySelector('ul');
        ul.addEventListener('click', function (e) {
            console.log(e.target.innerText);
        })
    </script>
</body>