DOM事件和事件委托

180 阅读2分钟

DOM事件模型

  • DOM事件模型分为捕获和冒泡,事件发生后,会在父元素于子元素之间传播,分为三个阶段。

    ( 1 ) 捕获阶段:事件从window对象自上而下向目标节点传播的阶段

    ( 2 ) 目标阶段:目标节点处理事件的阶段

    ( 3 ) 冒泡阶段:与捕获阶段相反,事件从目标节点自下而上向window对象传播的阶段

  • 给元素添加事件:el.addEventListener(eventName, callback,useCapture)

    event-name: 事件名称,可以是标准的DOM事件。

    callback: 事件触发时执行的回调函数,当事件触发时,函数会被注入一个参数为当前的事件对象 event

    useCapture: 默认是false,代表事件在冒泡阶段执行,true表示事件在捕获阶段执行

    const btn = document.getElementById('btn');
      btn.addEventListener("click", (e)=>{
          console.log(e)
      }, false);
    

事件委托

  • 由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方法叫做事件委托。

  • 事件委托的优点

    1. 减少内存消耗,提高性能,假设有一个div,里面有大量的button,我们需要在点击每个button项的时候响应一个事件
    <div id="div">
        <button>1</button>
        <button>2</button>
        <button>3</button>
        <button>4</button>
        <button>5</button>
        ...
        <button>n</button>
    </div>
    

    如果给每个button都绑定一个函数,那对于内存消耗是非常大的,效率上需要消耗很多性能。借助事件代理,我们只需要给父容器div绑定方法即可,这样不管点击的是哪一个后代元素,都会根据冒泡传播的传递机制,把容器的click行为触发,然后把对应的方法执行,根据事件源,我们可以知道点击的是谁,从而完成不同的事。

    const div = document.getElementById('div');
    div.addEventListener("click", (e)=>{
       const t = e.target;
       if(t.tagName.toLowerCase()==='button'){
           console.log('button被点击了')
           console.log('点击的对象是' + t.textContent)
       }
    });
    
    1. 动态绑定事件

    在很多时候,需要通过用户操作来动态的增删列表项元素,如果一开始给每个子元素绑定事件,那么在列表发生变化时,就需要重新给新增的元素绑定事件,给即将删去的元素解绑事件,如果用事件代理就会省去很多这样麻烦。