JavaScript事件委托的技术原理探讨示例


Posted in Javascript onApril 17, 2014

如今的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)'了。使用事件委托技术能让你避免对特定的每个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。基本概念非常简单,但仍有很多人不理解事件委托的工作原理。这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子。

假定我们有一个UL元素,它有几个子元素:

<ul id="parent-list"> 
<li id="post-1">Item 1</li> 
<li id="post-2">Item 2</li> 
<li id="post-3">Item 3</li> 
<li id="post-4">Item 4</li> 
<li id="post-5">Item 5</li> 
<li id="post-6">Item 6</li> 
</ul>

我们还假设,当每个子元素被点击时,将会有各自不同的事件发生。你可以给每个独立的li元素添加事件监听器,但有时这些li元素可能会被删除,可能会有新增,监听它们的新增或删除事件将会是一场噩梦,尤其是当你的监听事件的代码放在应用的另一个地方时。但是,如果你将监听器安放到它们的父元素上呢?你如何能知道是那个子元素被点击了?

简单:当子元素的事件冒泡到父ul元素时,你可以检查事件对象的target属性,捕获真正被点击的节点元素的引用。下面是一段很简单的JavaScript代码,演示了事件委托的过程:

// 找到父元素,添加监听器... 
document.getElementById("parent-list").addEventListener("click",function(e) { 
// e.target是被点击的元素! 
// 如果被点击的是li元素 
if(e.target && e.target.nodeName == "LI") { 
// 找到目标,输出ID! 
console.log("List item ",e.target.id.replace("post-")," was clicked!"); 
} 
});

第一步是给父元素添加事件监听器。当有事件触发监听器时,检查事件的来源,排除非li子元素事件。如果是一个li元素,我们就找到了目标!如果不是一个li元素,事件将被忽略。这个例子非常简单,UL和li是标准的父子搭配。让我们试验一些差异比较大的元素搭配。假设我们有一个父元素div,里面有很多子元素,但我们关心的是里面的一个带有”classA” CSS类的A标记:
// 获得父元素DIV, 添加监听器... 
document.getElementById("myDiv").addEventListener("click",function(e) { 
// e.target是被点击的元素 
if(e.target && e.target.nodeName == "A") { 
// 获得CSS类名 
var classes = e.target.className.split(" "); 
// 搜索匹配! 
if(classes) { 
// For every CSS class the element has... 
for(var x = 0; x < classes.length; x++) { 
// If it has the CSS class we want... 
if(classes[x] == "classA") { 
// Bingo! 
console.log("Anchor element clicked!"); 
// Now do something here.... 
} 
} 
} 
} 
});

上面这个例子中不仅比较了标签名,而且比较了CSS类名。虽然稍微复杂了一点,但还是很具代表性的。比如,如果某个A标记里有一个span标记,则这个span将会成为target元素。这个时候,我们需要上溯DOM树结构,找到里面是否有一个 A.classA 的元素。

因为大部分程序员都会使用jQuery等工具库来处理DOM元素和事件,我建议大家都使用里面的事件委托方法,因为这里工具库里都提供了高级的委托方法和元素甄别方法。

希望这篇文章能帮助你理解JavaScript事件委托的幕后原理,希望你也感受到了事件委托的强大用处!

Javascript 相关文章推荐
深入理解JavaScript系列(15) 函数(Functions)
Apr 12 Javascript
jquery1.10给新增元素绑定事件的方法
Mar 06 Javascript
js中把JSON字符串转换成JSON对象最好的方法
Mar 21 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
Sep 26 Javascript
jQuery使用fadein方法实现渐出效果实例
Mar 27 Javascript
JS控制FileUpload的上传文件类型实例代码
Oct 07 Javascript
JS同步、异步、延迟加载的方法
May 05 Javascript
js实现图片上传并预览功能
Aug 06 Javascript
layer弹出层父子页面事件相互调用方法
Aug 17 Javascript
Vue中用props给data赋初始值遇到的问题解决
Nov 27 Javascript
JavaScript实现移动端带transition动画的轮播效果
Mar 24 Javascript
前端性能优化建议
Sep 17 Javascript
JS实现div居中示例
Apr 17 #Javascript
淘宝网提供的国内NPM镜像简介和使用方法
Apr 17 #Javascript
js调用后台、后台调用前台等方法总结
Apr 17 #Javascript
JS下载文件|无刷新下载文件示例代码
Apr 17 #Javascript
你可能不知道的JavaScript的new Function()方法
Apr 17 #Javascript
在JS中解析HTML字符串示例代码
Apr 16 #Javascript
iframe的onreadystatechange事件在firefox下的使用
Apr 16 #Javascript
You might like
php自定义apk安装包实例
2014/10/20 PHP
多个Laravel项目如何共用migrations详解
2018/09/25 PHP
PHP数组遍历的几种常见方式总结
2019/02/15 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
iis6+javascript Add an Extension File
2007/06/13 Javascript
JavaScript中数组的排序、乱序和搜索实现代码
2011/11/30 Javascript
jQuery表格插件ParamQuery简单使用方法示例
2013/12/05 Javascript
javascript日期操作详解(脚本之家整理)
2015/09/05 Javascript
jQuery实现美观的多级动画效果菜单代码
2015/09/06 Javascript
修改jquery中dialog的title属性方法(推荐)
2016/08/26 Javascript
微信JSAPI支付操作需要注意的细节
2017/01/10 Javascript
微信小程序 支付功能开发错误总结
2017/02/21 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
深入了解javascript 数组的sort方法
2018/06/01 Javascript
JS中使用new Option()实现时间联动效果
2018/12/10 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
js通过canvas生成图片缩略图
2020/10/02 Javascript
[43:14]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
Python学习小技巧总结
2018/06/10 Python
Linux下多个Python版本安装教程
2018/08/15 Python
详解Python计算机视觉 图像扭曲(仿射扭曲)
2019/03/27 Python
python 进程的几种创建方式详解
2019/08/29 Python
python+django+rest框架配置创建方法
2019/08/31 Python
pytorch点乘与叉乘示例讲解
2019/12/27 Python
PyQt5中QTableWidget如何弹出菜单的示例代码
2020/02/23 Python
python中pyplot基础图标函数整理
2020/11/10 Python
中国海淘族值得信赖的海淘返利网站:55海淘
2017/01/16 全球购物
美国50岁以上单身人士约会平台:SilverSingles
2018/06/29 全球购物
SAZAC的动物连体衣和动物睡衣:Kigurumi Shop
2020/03/14 全球购物
技术总监个人的自我评价范文
2013/12/18 职场文书
高中自我鉴定
2013/12/20 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
会计专业自荐信
2014/06/03 职场文书
总经理助理岗位职责
2015/01/31 职场文书
一文搞懂Python Sklearn库使用
2021/08/23 Python
阿里云k8s服务升级时502错误 springboot项目应用
2022/04/09 Servers