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高级程序设计 阅读笔记(十七) js事件
Aug 14 Javascript
分享9点个人认为比较重要的javascript 编程技巧
Apr 27 Javascript
javascript实现youku的视频代码自适应宽度
May 25 Javascript
Backbone.js框架中简单的View视图编写学习笔记
Feb 14 Javascript
JavaScript实现in-place思想的快速排序方法
Aug 07 Javascript
AngularJs Dependency Injection(DI,依赖注入)
Sep 02 Javascript
Js获取当前日期时间及格式化代码
Sep 17 Javascript
ES6学习教程之模板字符串详解
Oct 09 Javascript
深入浅析Vue全局组件与局部组件的区别
Jun 15 Javascript
vue组件系列之TagsInput详解
May 14 Javascript
jquery+ajax实现异步上传文件显示进度条
Aug 17 jQuery
微信小程序自定义支持图片的弹窗
Dec 21 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读取30天之内的根据算法排序的代码
2008/04/06 PHP
Windows下XDebug 手工配置与使用说明
2010/07/11 PHP
PHP获取当前文件的父目录方法汇总
2016/07/21 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
js 模拟实现类似c#下的hashtable的简单功能代码
2010/01/24 Javascript
jQuery源码分析-02正则表达式 RegExp 常用正则表达式
2011/11/14 Javascript
JS操作Cookies包括(读取添加与删除)
2012/12/26 Javascript
js获取height和width的方法说明
2013/01/06 Javascript
js中的this关键字详解
2013/09/25 Javascript
jquery增加和删除元素的方法
2015/01/14 Javascript
详解Javascript几种跨域方式总结
2017/02/27 Javascript
对vue中v-if的常见使用方法详解
2018/09/28 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
vue-froala-wysiwyg 富文本编辑器功能
2019/09/19 Javascript
Vue封装全局过滤器Filters的步骤
2020/09/16 Javascript
Python设计模式之观察者模式实例
2014/04/26 Python
python实现的登录和操作开心网脚本分享
2014/07/09 Python
Python类属性的延迟计算
2016/10/22 Python
Python小工具之消耗系统指定大小内存的方法
2018/12/03 Python
Python实现Event回调机制的方法
2019/02/13 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
Python常用模块sys,os,time,random功能与用法实例分析
2020/01/07 Python
Tensorflow:转置函数 transpose的使用详解
2020/02/11 Python
matplotlib部件之矩形选区(RectangleSelector)的实现
2021/02/01 Python
Farnell德国:电子元器件供应商
2018/07/10 全球购物
波兰在线体育用品商店:Hop-Sport.pl
2019/07/23 全球购物
新加坡最早生产电动滑板车的制造商之一:FunsToTheFore
2020/09/08 全球购物
电大本科自我鉴定
2014/02/05 职场文书
教育技术学专业职业规划书
2014/03/03 职场文书
《黄山奇石》教学反思
2014/04/19 职场文书
学校纪律作风整改措施思想汇报
2014/10/11 职场文书
餐厅保洁员岗位职责
2015/04/10 职场文书
十二生肖观后感
2015/06/12 职场文书
房产遗嘱范本
2015/08/06 职场文书
教师节主题班会教案
2015/08/17 职场文书
Pytest实现setup和teardown的详细使用详解
2021/04/17 Python