当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JS:事件委托

JS:事件委托

2018年12月08日  | 移动技术网IT编程  | 我要评论

事件委托

  1. 事件流

    事件流描述的是从页面中接收事件的顺序。---js高级程序设计(第3版)

    dom level 2 events规定的事件流有三个阶段:①事件捕获阶段、②处于目标阶段、③事件冒泡阶段

    capture_and_bubbling

  2. 事件委托

    当需要添加的事件过多时,可以使用事件委托,而事件委托实际上利用了事件冒泡的特性。

    使用事件委托还需了解事件对象(event):在触发dom上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。

    在此仅需知道在dom标准中,event拥有一个target属性表示事件目标。

    event.target是一个触发事件的对象的引用。它与event.currenttarget不同, 当事件处理程序在事件的冒泡或捕获阶段被调用时。(mdn)

    具体event详情可以查看mdn:event


    如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并将事件监听器气泡的影响设置为每个子节点,而不是每个子节点单独设置事件监听器。(mdn)

    以下面的html代码为例:

    <ul id="list">
        <li id="one">do something</li>
        <li id="two">do something</li>
        <li id="three">do something</li>
    </ul>

    当需求是单击上面每个li标签都会执行各种操作时,使用事件委托是较好的选择。

    // bad (逐个 li 添加事件)
    let item1 = document.getelementbyid('one');
    let item2 = document.getelementbyid('two');
    let item3 = document.getelementbyid('three');
    
    item1.addeventlistener('click', function(){...}, false);
    item1.addeventlistener('click', function(){...}, false);
    item1.addeventlistener('click', function(){...}, false);
    
    // event delegation (事件委托)
    let list = document.getelementbyid('list');
    list.addeventlistener('click', function(e){
        if (e.target && e.target.nodename == 'li') {
            switch (e.target.id) {
              case 'one':
                do something;
                break;
    
              case 'two':
                do something;
                break;
    
              case 'three':
                do something;
                break;
            }
          }
    }, false);

    注意:当li标签被如pdiv等撑满时,点击的targetp标签而不是li标签会导致无法正确执行click事件。

    以下面的html代码为例:

    <ul id="list">
        <li id="one">do something</li>
        <li id="two">do something</li>
        <!-- 这里的 li 里面有个 p 标签 -->
        <li id="three"><p>do something</p></li>
      </ul>

    这样的情况可以使用递归 or 循环来处理,毕竟事件委托是利用事件冒泡的特性。

    //递归
    let list = document.getelementbyid('list');
    list.addeventlistener('click', function(e){
     eventdelegation(e.target);
    }, false);
    
    function eventdelegation(target) {
     if (target && target.nodename == 'li') {
            switch (target.id) {
              case 'one':
                do something;
                return;
    
              case 'two':
                do something;
                return;
    
              case 'three':
                do something;
                return;
            }
        }
        return eventdelegation(target.parentnode);
    }
  3. 使用事件委托的优点

    a.减少dom操作,使事件处理时间减少。
    b.减少内存空间的使用,提升性能。

    因为在javascript中,每个函数都是对象,对象越多,占用的内存也就越多,合理使用事件委托可以减少内存的占用。

  4. 注意事项

    比较适合使用事件委托的事件:clickmousedownmouseup等,而如mouseoutmouseover等则不太适合使用事件委托(虽然mouseout这些事件也冒泡,但通常需要确定元素的位置,所以不太推荐使用事件委托)。

    另外不会冒泡的事件是不适合使用事件委托的。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网