JavaScript事件冒泡与事件捕获

事件冒泡(Event Bubbling)

事件冒泡是事件流的一个阶段,事件最初在目标元素上触发,然后逐层向上传播到其父级元素,直到到达最顶层的documentwindow。冒泡机制允许父级元素在事件向上传播时捕获并处理该事件。

事件冒泡是事件流执行的默认顺序

简而言之,事件冒泡指的是从里到外逐层传递,先触发子元素,再逐步传递给父元素。

<body>
    <div class="square red">
        <div class="square blue">
            <div class="square green"></div>
        </div>
    </div>
</body>
</html>
<script>
    document.querySelector('.red').addEventListener('click', function(event) {
        {
            alert('红色区域被点击了');
        }
    });

    document.querySelector('.blue').addEventListener('click', function(event) {
        {
            alert('蓝色区域被点击了');
        }
    });

    document.querySelector('.green').addEventListener('click', function(event) {
        alert('绿色区域被点击了');
    });
</script>

像这样,当我们点击位于最内部的“绿色”,弹出顺序是由内向外的绿、蓝、红。

事件捕获(Event Capturing)

事件捕获是事件流的另一个阶段,事件首先从最顶层的祖先元素(如document)开始向下传播,直到到达目标元素。在捕获阶段,父级元素可以在事件到达目标之前处理事件。事件捕获是事件冒泡的相反方向,较少使用,但可以通过设置监听器选项来指定事件在捕获阶段触发。

简而言之,事件捕获是从外到里逐层传递,先触发父元素,再逐步传递给子元素。

<script>
    document.querySelector('.red').addEventListener('click', function(event) {
        {
            alert('红色区域被点击了');
        }
    },true);

    document.querySelector('.blue').addEventListener('click', function(event) {
        {
            alert('蓝色区域被点击了');
        }
    },true);

    document.querySelector('.green').addEventListener('click', function(event) {
        alert('绿色区域被点击了');
    },true);
</script>

在这里,我们将addEventListener事件的第三个参数改为了true (因为其默认是False,即默认执行的是事件冒泡),由此我们将这一事件流的执行改为了事件捕获。当我们点击最内侧的“绿色”,弹出的顺序是由外向内的红、蓝、绿。

那我们如何实现点击绿色只弹出绿色的操作呢?

这里的修改主要有以下几点:

  1. 将所有事件监听器的第三个参数 true 改为 false,这样使用事件冒泡而不是事件捕获。

  2. 在绿色区域的事件处理函数中,添加了 event.stopPropagation(),这会阻止事件继续冒泡到父元素。

  3. 对于红色和蓝色区域,添加了条件判断 if (event.target.classList.contains('...')),这确保只有当点击的是相应颜色的区域时才会触发 alert。

<script>
    document.querySelector('.red').addEventListener('click', function(event) {
        if (event.target.classList.contains('red')) {
            alert('红色区域被点击了');
        }
    },true);

    document.querySelector('.blue').addEventListener('click', function(event) {
        if (event.target.classList.contains('blue')) {
            alert('蓝色区域被点击了');
        }
    },true);

    document.querySelector('.green').addEventListener('click', function(event) {
        alert('绿色区域被点击了');
    },true);
</script>

这样修改后,点击绿色区域只会弹出"绿色区域被点击了",而不会触发蓝色和红色区域的事件。点击蓝色区域会弹出"蓝色区域被点击了",点击红色区域(不包括蓝色和绿色部分)会弹出"红色区域被点击了"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值