事件冒泡事件捕获及事件委托

39次阅读

共计 1886 个字符,预计需要花费 5 分钟才能阅读完成。

事件冒泡与事件捕获

事件冒泡和捕获分别是是由微软和网景公司提出的, 这两个概念都是为了解决页面中事件流 (事件发生顺序) 的问题。

    <div>
        <p> 点击 </p>
    </div>

当父元素 (div) 与子元素 (p) 上都绑定事件时:
        事件冒泡: 子级元素先触发, 父级元素后触发, 即 p 先触发,div 后触发。发生事件的顺序为 p -> div -> body -> html -> document。
        事件捕获: 父级元素先触发, 子级元素后触发, 即 div 先触发,p 后触发。发生事件的顺序为 document -> html -> body -> div -> p。

在 DOM0 级事件中 (ele.onclick=function(){}), 在 IE、Firefox、Chrome、opera 下事件执行顺序都是事件冒泡。
在 DOM2 级事件中(ele.addEventListener(event, fn, boolean)), 当第 3 个参数为 true 时表示事件捕获, 为 false 时表示事件冒泡, 默认为 false。

事件委托

 事件委托: 利用事件冒泡的原理, 将多个子元素上的 (一类型) 事件, 放在父元素上, 在父元素上创建一个事件处理程序来管理这一类型的所有事件。事件委托的优点:
    1) 由于每一个函数都是对象, 对象会占用内容, 内存的占用关系到性能, 而使用事件委托后, 会减少事件处理程序。因此, 减少了内存占用, 性能更好。2) 如果要为许多 DOM 元素绑定事件, 需要多长访问 DOM, 设置事件处理程序所需时间更长, 整个页面就绪需要的时间越多。事件委托技术可以避免对每个字元素添加事件监听器,减少操作 DOM 节点的次数,从而减少浏览器的重绘和重排,提高代码的性能。

例:

     <ul>
        <li data-id="1">1</li>
        <li data-id="2">2</li>
        <li data-id="3">3</li>
    </ul>
    
    <script>
        let ulEle = document.querySelector('ul');
        ulEle.onclick = function (event) {
            let val = event.target.dataset.id;
            if (typeof val !== 'undefined') {alert(val);
            }
        }
    </script>

扩展

DOM0 事件绑定和 DOM2 级事件绑定

DOM0 事件绑定
    DOM0 事件绑定的原理
        1. 给当前元素的某一私有属性(onXXX)赋值的过程;(之前属性默认值是 null,如果我们赋值了一个函数,就相当于绑定了一个方法)2. 当我们赋值成功(赋值一个函数),此时浏览器会把 DOM 元素和赋值的的函数建立关联,以及建立 DOM 元素的行为监听,当某一行为被用户触发,浏览器会把赋值的函数执行
        
    DOM0 事件绑定的特点:
        1. 在 DOM0 级事件绑定中, 只能给当前元素的某一个行为绑定一个方法, 绑定多个方法时, 最后一次绑定的事件会替换前面绑定的。2. 移除事件绑定时只需要赋值为 null。DOM2 事件绑定:
    DOM2 事件绑定的原理
        1.DOM2 事件绑定使用的 addEventListener/attachEvent 方法都是在 eventTarget 这个内置类的原型上定义的, 调用的时候, 首先要通过原型链找到这个方法, 然后执行完成事件的绑定效果。2. 浏览器会给当前元素的行为开辟一个事件池(事件队列)[浏览器有一个统一的事件池, 每个元素绑定的行为都在这里, 通过相关标准区分], 通过 addEventListener/attachEvent 进行事件绑定时, 会把绑定的方法放在事件池中。3. 当元素的某一行为被触发,浏览器回到对应事件池中,把当前放在事件池的所有方法按序依次执行
    
    DOM2 事件绑定的特点
        1. 所有 DOM0 支持的行为,DOM2 都可以用,DOM2 还支持 DOM0 没有的事件行为(这样说比较笼统)【浏览器会把一些常用事件挂载到元素对象的私有属性上,让我们可以实现 DOM0 事件绑定,DOM2:凡是浏览器给元素天生设置的事件在 DOM2 中都可以使用】2.DOM2 中可以给当前元素的某一事件行为绑定多个不同方法(因为绑定的所有方法都放在事件池中)3. 事件的移除: 事件类型、绑定的方法、传播阶段三个完全一致,才可以完成移除(因此在绑定方法时,尽量不要用匿名函数,否则不好移除)

注: 在 DOM 第一代升级迭代的时候,事件绑定依然沿用 DOM0 绑定的方式。

参考文章:
        JS 基础知识(十一)DOM0 和 DOM2 级事件:
https://blog.csdn.net/qq_2338…
        浅谈事件冒泡与事件捕获: https://segmentfault.com/a/11…

正文完
 0