使用事件委托清除事件冒泡

1.先看看常见的一种清除事件冒泡方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        #upper{
            width: 300px;
            height: 300px;
            background: red;
        }
        #center{
            width: 200px;
            height: 200px;
            background: aqua;
        }
        #lower{
            width: 100px;
            height: 100px;
            background: yellow;
        }
    </style>
</head>
<body>
<div id="upper">
    <div id="center">
        <div id="lower"></div>
    </div>
</div>
<script>
    var upper = document.getElementById('upper');
    var center = document.getElementById('center');
    var lower = document.getElementById('lower');
    upper.onclick = function (ev) {
        console.log('外');
    };
    center.onclick = function (ev) {
      console.log('中');
        ev.stopPropagation();
    };
    lower.onclick = function (ev) {
        console.log('内');
        ev.stopPropagation();
    };
</script>
</body>
</html>

2.使用事件委托

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        body{
            background: antiquewhite;
        }
        #upper{
            width: 300px;
            height: 300px;
            background: red;
        }
        #center{
            width: 200px;
            height: 200px;
            background: aqua;
        }
        #lower{
            width: 100px;
            height: 100px;
            background: yellow;
        }
    </style>
</head>
<body>
<div id="upper">
    <div id="center">
        <div id="lower"></div>
    </div>
</div>
<script>
    var upper = document.getElementById('upper');
    var center = document.getElementById('center');
    var lower = document.getElementById('lower');

    var body = document.getElementsByTagName('body')[0];
    body.onclick = function (ev) {
        var ev = ev||window.event;
        var target = ev.target||ev.srcElement;
        switch (target.id){
            case 'upper':
                console.log('外');
                break;
            case 'center':
                console.log('中');
                break;
            case 'lower':
                console.log('内');
                break;
        }
    };
</script>
</body>
</html>

JavaScript 中的事件委托事件冒泡是处理 DOM 事件的重要机制,它们共同构成了事件流的基础,并在实际开发中提供了优化性能和简化代码逻辑的能力。 ### 事件冒泡(Event Bubbling) 事件冒泡是指当一个元素上的事件被触发时,该事件会从最具体的元素(例如某个 `<div>`)开始向上逐级传播到其父元素、祖先元素,直到 `window` 对象。这种向上传播的过程称为“冒泡”。 例如,如果点击了一个嵌套在多个父元素中的按钮,那么点击事件将首先在按钮本身触发,然后依次在其直接父元素、祖父元素等上触发[^1]。 ```javascript // 示例:事件冒泡演示 document.getElementById('inner').addEventListener('click', function () { console.log('Inner element clicked'); }); document.getElementById('outer').addEventListener('click', function () { console.log('Outer element clicked'); }); ``` 在这个例子中,点击 `inner` 元素后,控制台输出顺序为: ``` Inner element clicked Outer element clicked ``` 这表明事件从内层元素向外层元素传播。 ### 事件委托(Event Delegation) 事件委托是一种利用事件冒泡机制的技术。它通过将事件监听器设置在外层元素上,而不是每个子元素上,从而实现对多个子元素事件的统一管理。这样做的好处包括减少内存消耗和简化动态内容的事件绑定[^4]。 ```javascript // 示例:使用事件委托 document.querySelector('ul').addEventListener('click', function (event) { if (event.target.tagName === 'LI') { console.log('Clicked on:', event.target.textContent); } }); ``` 在这个例子中,所有 `<li>` 元素的点击事件都由其父元素 `<ul>` 统一处理。即使后续新增或删除 `<li>` 元素,也不需要重新绑定事件监听器。 ### 事件捕获(Event Capturing) 与事件冒泡相对应的是事件捕获。在事件捕获阶段,事件从最不具体的元素(如 `window`)向下传播到最具体的元素(目标元素)。开发者可以在添加事件监听器时指定是否在捕获阶段执行[^3]。 ```javascript // 示例:事件捕获 document.getElementById('outer').addEventListener('click', function () { console.log('Outer element captured'); }, true); // 第三个参数为 true 表示在捕获阶段执行 document.getElementById('inner').addEventListener('click', function () { console.log('Inner element captured'); }, true); ``` 点击 `inner` 元素后,控制台输出顺序为: ``` Outer element captured Inner element captured ``` 这表明事件在捕获阶段是从外层向内层传播的。 ### 控制事件传播 有时我们希望阻止事件继续传播,避免不必要的副作用。可以使用以下方法: - `event.stopPropagation()`:阻止事件继续在当前阶段传播。 - `event.preventDefault()`:阻止事件的默认行为(如链接跳转、表单提交等)。 需要注意的是,在 IE 浏览器中,使用 `event.cancelBubble = true` 来代替 `stopPropagation()`[^2]。 ### 实际应用场景 - **动态内容管理**:如异步加载列表项并绑定点击事件使用事件委托可避免频繁添加/移除监听器。 - **性能优化**:减少页面中注册的事件监听器数量,降低内存占用。 - **组件化开发**:React 等框架内部也大量使用事件委托来提升性能和简化事件处理逻辑[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值