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 相关文章推荐
js 与或运算符 || &amp;&amp; 妙用
Dec 09 Javascript
JS随即打乱数组实现代码
Dec 03 Javascript
JQuery+Ajax无刷新分页的实例代码
Feb 08 Javascript
javascript 拷贝节点cloneNode()使用介绍
Apr 03 Javascript
JavaScript的removeChild()函数用法详解
Dec 27 Javascript
教你用javascript实现随机标签云效果_附代码
Mar 16 Javascript
AngularJS动态加载模块和依赖的方法分析
Nov 08 Javascript
Vue实现类似Spring官网图片滑动效果方法
Mar 01 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
Mar 07 Javascript
laypage.js分页插件使用方法详解
Jul 27 Javascript
js中Function引用类型常见有用的方法和属性详解
Dec 11 Javascript
微信小程序实现菜单左右联动
May 19 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(1) php开发环境配置
2010/02/15 PHP
破解.net程序(dll文件)编译和反编译方法
2013/01/31 PHP
php多层数组与对象的转换实例代码
2013/08/05 PHP
php正则取img标记中任意属性(正则替换去掉或改变图片img标记中的任意属性)
2013/08/13 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
2016/10/18 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
php array_chunk()函数用法与注意事项
2019/07/12 PHP
转自Jquery官方 jQuery1.1.3发布,速度提升800%,体积保持20K
2007/08/19 Javascript
jquery实现兼容浏览器的图片上传本地预览功能
2013/10/14 Javascript
jquery使用淘宝接口跨域查询手机号码归属地实例
2013/11/28 Javascript
jQuery中click事件的定义和用法
2014/12/20 Javascript
JavaScript学习笔记之JS对象
2015/01/22 Javascript
写给小白的JavaScript引擎指南
2015/12/04 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
2016/05/30 Javascript
Bootstrap基本样式学习笔记之按钮(4)
2016/12/07 Javascript
微信小程序request出现400的问题解决办法
2017/05/23 Javascript
AngularJS 验证码60秒倒计时功能的实现
2017/06/05 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
2018/03/22 Javascript
layui 表格操作列按钮动态显示的实现方法
2019/09/06 Javascript
python操作日期和时间的方法
2014/03/11 Python
python 产生token及token验证的方法
2018/12/26 Python
原生python实现knn分类算法
2019/10/24 Python
tensorflow 环境变量设置方式
2020/02/06 Python
windows、linux下打包Python3程序详细方法
2020/03/17 Python
Windows下pycharm安装第三方库失败(通用解决方案)
2020/09/17 Python
python爬虫实现爬取同一个网站的多页数据的实例讲解
2021/01/18 Python
匡威爱尔兰官网:Converse爱尔兰
2019/06/09 全球购物
材料加工硕士生求职信
2013/10/10 职场文书
路政管理专业推荐信
2013/11/11 职场文书
2014年党员创先争优承诺书
2014/05/29 职场文书
2014年教务工作总结
2014/12/03 职场文书
2014年林业工作总结
2014/12/05 职场文书
齐云山导游词
2015/02/06 职场文书
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL
Java实现添加条码或二维码到Word文档
2022/06/01 Java/Android