基本概念

事件代理(Event Delegation),又称之为事件委托。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。

举个通俗的例子

比如一个宿舍的同学同时快递到了,一种方法就是他们一个个去领取,还有一种方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一 一分发给每个宿舍同学;

在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的宿舍长就是代理的元素,所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。

事件冒泡

前面提到事件委托的原理是DOM元素的事件冒泡,那么事件冒泡是什么呢?

一个事件触发后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段

如上图所示,事件传播分成三个阶段:

  • 捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件;
  • 目标阶段:在目标节点上触发,称为“目标阶段”
  • 冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层;

事件委托的优点

【1】可以大量节省内存占用,减少事件注册,比如在ul上代理所有li的click事件就非常棒

<ul id="list"><li>item 1</li><li>item 2</li><li>item 3</li>......<li>item n</li>
</ul>
// ...... 代表中间还有未知数个 li

如上面代码所示,如果给每个li列表项都绑定一个函数,那对内存的消耗是非常大的,因此较好的解决办法就是将li元素的点击事件绑定到它的父元素ul身上,执行事件的时候再去匹配判断目标元素。

【2】可以实现当新增子对象时无需再次对其绑定(动态绑定事件)

假设上述的例子中列表项li就几个,我们给每个列表项都绑定了事件;

在很多时候,我们需要通过 AJAX 或者用户操作动态的增加或者删除列表项li元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件;

如果用了事件委托就没有这种麻烦了,因为事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配的;所以使用事件在动态绑定事件的情况下是可以减少很多重复工作的。

基本实现

【1】JavaScript原生实现事件委托

比如我们有这样的一个 HTML 片段:

<ul id="myLinks"><li id="goSomewhere">Go somewhere</li><li id="doSomething">Do something</li><li id="sayHi">Say hi</li>
</ul>

按照传统的做法,需要像下面这样为它们添加 3 个事 件处理程序

    var item1 = document.getElementById("goSomewhere");var item2 = document.getElementById("doSomething");var item3 = document.getElementById("sayHi");item1.onclick = function() {location.href = "http://www.baidu.com";};item2.onclick = function() {document.title = "事件委托";};item3.onclick = function() {alert("hi");};

如果在一个复杂的 Web 应用程序中,对所有可单击的元素都采用这种方式,那么结果就会有数不 清的代码用于添加事件处理程序。此时,可以利用事件委托技术解决这个问题。使用事件委托,只需在 DOM 树中尽量最高的层次上添加一个事件处理程序,如下面的例子所示

    var item1 = document.getElementById("goSomewhere");var item2 = document.getElementById("doSomething");var item3 = document.getElementById("sayHi");document.addEventListener("click", function (event) {var target = event.target;switch (target.id) {case "doSomething":document.title = "事件委托";break;case "goSomewhere":location.href = "http://www.baidu.com";break;case "sayHi": alert("hi");break;}})

【2】jQuery事件delegate()实现事件委托

delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。

格式:$(selector).delegate(childSelector, event, data, function)

参数 描述
childSelector 必需,规定要附加事件处理程序的一个或多个子元素。
event

必需,规定附加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。

data 可选,规定传递到函数的额外数据。
function 必需,规定当事件发生时运行的函数。
<!DOCTYPE html>
<html><head><meta charset="utf-8"><script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head><body><ul id="myLinks"><li id="goSomewhere">Go somewhere</li><li id="doSomething">Do something</li><li id="sayHi">Say hi</li></ul><script>$(document).ready(function () {$("#myLinks").delegate("#goSomewhere", "click", function () {location.href = "http://www.baidu.com";});});</script></body></html>

使用事件委托注意事项

使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。

JavaScript事件代理(事件委托)相关推荐

  1. JavaScript事件代理和委托

    2019独角兽企业重金招聘Python工程师标准>>> 浏览器的事件冒泡 当事件发生后,这个事件就要开始传播.例如我们点击一个按钮时,就会产生一个click事件,但这个按钮本身不能处 ...

  2. 简诉事件代理(事件委托)及其优点

    事件代理 不给每个子节点单独设置事件监听器,而是设置在其父节点上,然后利用冒泡原理设置每个子节点. 优点 1. 减少内存消耗和 dom 操作,提高性能. 在 JavaScript 中,添加到页面上的事 ...

  3. JS 事件代理和事件委托

    目录 事件委托的概念理解 为什么要用事件委托 事件委托的原理: 事件代理(委托)实现 总结: 事件委托的概念理解 为什么叫事件委托?它还有一个名字叫事件代理. JavaScript高级程序设计上讲:事 ...

  4. 使用事件代理实现vue的手风琴组件

    1.为什么要使用事件代理? 在项目中要做一个手风琴组件,需求是页面created事件中请求数据,以显示在列表中,加载数据时显示"正在加载",没有数据了就显示"没有更多数据 ...

  5. 用例子解释事件模型和事件代理

    事件模型 事件传播模型 在说事件代理之前,先来说一下事件模型. 在浏览器开发的早期,面对事件触发模型的问题,所有的程序员都认为事件触发不应该是直接触发的,而应该在文档中有一个传播的过程,然而事件传播的 ...

  6. Event事件-1:addEventListener事件监听 / 事件冒泡事件捕获 / 事件委托 / preventDefault 阻止默认行为 / cancelBubble、stopPropa...

    addEventListener 事件监听器 target.addEventListener(type, listener[, options|useCapture])     添加事件监听 参数: ...

  7. 事件链、事件代理、页面的渲染过程、style的操作、防抖与节流【DOM(四)】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 1.事件链(冒泡目标捕获) (1)事件链原理 (2)阻止冒泡和默认事件 2.事件代理(面试笔试题重点) 3. ...

  8. a标签点击事件_DOM事件机制

    前言 本文主要介绍DOM事件级别.DOM事件模型.事件流.事件代理和Event对象常见的应用,希望对你们有些帮助和启发! 一.DOM事件级别 DOM级别一共可以分为四个级别:DOM0级.DOM1级.D ...

  9. JavaScript系列—简述JS中的事件委托和事件代理

    JS中的事件委托和事件代理 什么是事件委托? 事件委托还有一个名字叫事件代理,JS高程上讲:事件委托就是利用事件冒泡,只制定一个时间处理程序,就可以管理某一类型的所有事件.我用取快递来解释这个现象: ...

  10. js中的事件委托或是事件代理详解(转载)

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

最新文章

  1. javah生成JNI头文件
  2. Ubuntu系统安装搜狗输入法详细教程
  3. 如何列出Git 1.7+中的所有远程分支?
  4. 好程序员web前端分享数组及排序、去重和随机点名
  5. DL之CNN:卷积神经网络算法简介之原理简介——CNN网络的3D可视化(LeNet-5为例可视化)
  6. 直播 | ACL 2021论文解读:为结构预测问题自动寻找更强的词嵌入拼接方式
  7. 软件登录界面设计分享
  8. AssetBundle Workflow
  9. C++获取本机的ip地址程序
  10. 高可用Eureka注册中心配置说明(双机部署)
  11. 最强阿里面试126题:数据结构+并发编程+Redis+设计模式+微服务
  12. python工作状态_[Python设计模式] 第16章 上班,干活,下班,加班——状态模式
  13. 我参与的一个项目总结
  14. BUAAOO电梯作业总结
  15. unity三维地形制作
  16. java pojo 类 怎么写_[转]Java中的POJO类
  17. Python实现图片转pdf
  18. 前端程序员为何焦虑?web前端未来终将是什么样?
  19. 蓝桥杯2020年第十届C/C++省赛A组第4题-迷宫(bfs)
  20. geoserver发布切片影像地图

热门文章

  1. sam格式的结构和意义_sam概述
  2. 无线测温采集设备及无线测温监控系统的选型指导-安科瑞王婧
  3. 「面试必背」Elasticsearch面试题(收藏)
  4. Linux基本知识总结、常用命令教程、shell脚本开发、编辑器及调试器的使用教程
  5. 智点木门软件为百闰门业解决哪些问题?
  6. Gebru被辞退的背后真相:指出BERT的4大危害,威胁谷歌商业利益
  7. 二、MySQL 介绍及 MySQL 安装与配置
  8. 缺陷跟踪系统BugTracker。 以下对使用
  9. Python:蒙特卡罗方法模拟解决三门问题
  10. 电子宠物游戏(附C++源码)