事件委托

  1. 事件流

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

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

  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这些事件也冒泡,但通常需要确定元素的位置,所以不太推荐使用事件委托)。

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

JS:事件委托的更多相关文章

  1. JS事件委托学习(转)

    JS 事件委托就是利用冒泡原理,把事件加到父级上触发,执行效果. 好处: 1.提高性能 2.新添加的元素还会有之前的事件     <</</</</li></ ...

  2. JS事件委托的原理和应用

    js事件委托也叫事件代理,实际上事件委托就是通过事件冒泡实现的,所谓的事件就是onclick,onmouseover,ondown等等,那么委托呢?委托就是指本来这个事是要你自己做的,但是你却让别人帮 ...

  3. js事件委托 jQuery写法

    http://www.cnblogs.com/liugang-vip/p/5616484.html 不是抄的,这篇文章写的细 这是js 事件委托写法 <!DOCTYPE html> < ...

  4. 原生js事件委托(事件代理)方法扩展

    原生js事件委托(事件代理)方法扩展: 通过Node底层原型扩展委托方法 /** * 事件委托方法 * @param eventName {string}:事件名称,如'click' * @param ...

  5. js事件委托

    什么是事件委托:通俗的讲,onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件. 也 ...

  6. 彻底弄懂JS事件委托的概念和作用

    一.写在前头    接到某厂电话问什么是事件代理的时候,一开始说addEventListener,然后他说直接绑定新的元素不会报dom不存在的错误吗?然后我就混乱了,我印象中这个方法是可以绑定新节点的 ...

  7. js事件委托篇(附js一般写法和js、jq事件委托写法)

    参考: jQuery代码优化:事件委托篇 使用该技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器被添加在他们的父元素上,事件监听器会分析从子元素上冒泡上来的事件,并找到是哪个子元素事件. ...

  8. js事件委托和jQuery事件绑定on , off , one , bind , unbind , die

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  9. js 事件委托 事件代理

    JavaScript高级程序设计上解释:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 通过例子类比: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三 ...

  10. js事件委托或事件代理

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

随机推荐

  1. [开源,学习,分享]UWP第三方简书客户端分享

    简介 Windows10正式版发布到现在,我利用零零碎碎的一些时间对UWP进行一些学习,也基于这门技术开发了一个第三方的简书App. 基本界面 优酷视频: http://v.youku.com/v_s ...

  2. Python学习网站

    Python Website: https://www.python.orgSource code: https://github.com/python/cpython Issue tracker: ...

  3. 基于beego orm 针对oracle定制

    目前golang的ORM对oracle支持都没有mysql那样完整,一个orm要同时兼容mysql和oracle由于在sql语法上区别,会使整orm变的非常臃肿. 本项目是在beego orm上修改, ...

  4. 《C++ Primer (V4)》读书笔记

    第2章 变量和基本类型 1.(P56)如果使用class关键字来定义类,那么定义在第一个访问标号前的任何成员都隐式指定为private:如果使用struct关键字,那么这些成员都是public. 第7 ...

  5. Netty学习第二节Java IO通信

    一.Java IO通信 名词解释: BIO通信:       采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端连接,在接收到客户端请求后,为每一个客户端建立一个新的线程负 ...

  6. 优秀前端工程师必备:" checkbox & radio--单钩 & 多钩 "大比较:你是♂||♀ , 还是 ♂&♀

    1 单选: type="radio"  需求: 男女input只能选择一个 <input type="radio" name="sex" ...

  7. Exception in thread Thread-3:第三个线程意外

    Status:Executing -train.py 02/09/2019 09:33:38 INFO Log level set to: INFO Using TensorFlow backend. ...

  8. java基础-day2

    第02天 java基础知识 今日内容介绍 u Eclipse的安装.配置及使用 u 运算符 u 键盘录入 第1章   Eclipse开发工具 1.1  Eclipse概述和安装 Eclipse是一个I ...

  9. android周期性任务

    一般任务调度机制的实现方式主要有: Thread sleep.Timer.ScheduledExecutor.Handler和其他第三方开源库.android的AlarmManager 1. Time ...

  10. VS2010与Qt5.1.0的集成

    早就听说qt可以集成到VS中,就是一直没尝试过.一直在使用qt creator,也没觉得它有什么不好.可最近VS用多了,我发现一个qt creator中很不好的毛病,就是代码自动完成时,creator ...