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 相关文章推荐
优化网页之快速的呈现我们的网页
Jun 29 Javascript
分享一个自定义的console类 让你不再纠结JS中的调试代码的兼容
Apr 20 Javascript
关于JavaScript的面向对象和继承有利新手学习
Jan 11 Javascript
js创建对象的方式总结
Jan 10 Javascript
js实现发送验证码后的倒计时功能
May 28 Javascript
原生JS简单实现ajax的方法示例
Nov 29 Javascript
工厂模式在JS中的实践
Jan 18 Javascript
原生JS实现简单放大镜效果
Feb 08 Javascript
jQuery图片切换动画效果
Feb 28 Javascript
vue-router 学习快速入门
Mar 01 Javascript
微信小程序云开发之数据库操作
May 18 Javascript
JS实现排行榜文字向上滚动轮播效果
Nov 26 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
利用static实现表格的颜色隔行显示的代码
2007/09/02 PHP
CodeIgniter框架提示Disallowed Key Characters的解决办法
2014/04/21 PHP
利用php_imagick实现复古效果的方法
2016/10/18 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
PHP实现多图上传和单图上传功能
2018/05/17 PHP
JavaScript.The.Good.Parts阅读笔记(一)假值与===运算符
2010/11/16 Javascript
jQuery简单实现验证邮箱格式
2015/07/15 Javascript
JavaScript实现删除,移动和复制文件的方法
2015/08/05 Javascript
jquery实现点击向下展开菜单项(伸缩导航)效果
2015/08/22 Javascript
浅析JavaScript回调函数应用
2016/05/22 Javascript
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
Vuerouter的beforeEach与afterEach钩子函数的区别
2018/12/26 Javascript
vue.js实现的幻灯片功能示例
2019/01/18 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
2019/10/23 Javascript
VUEX 数据持久化,刷新后重新获取的例子
2019/11/12 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
小程序自定义导航栏兼容适配所有机型(附完整案例)
2020/04/26 Javascript
javascript前端实现多视频上传
2020/12/13 Javascript
Django的数据模型访问多对多键值的方法
2015/07/21 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
Python闭包函数定义与用法分析
2018/07/20 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
Keras在训练期间可视化训练误差和测试误差实例
2020/06/16 Python
Python drop方法删除列之inplace参数实例
2020/06/27 Python
解决Ubuntu18中的pycharm不能调用tensorflow-gpu的问题
2020/09/17 Python
python实现计算图形面积
2021/02/22 Python
西班牙在线宠物商店:zooplus.es
2017/02/24 全球购物
巴西电子产品购物网站:Saldão da Informática
2018/01/09 全球购物
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
2014年五四青年节活动策划书
2014/04/22 职场文书
护士节活动总结
2014/08/29 职场文书
兼职安全员岗位职责
2015/02/15 职场文书
党员个人自我评价
2015/03/03 职场文书
浏览器常用基本操作之python3+selenium4自动化测试(基础篇3)
2021/05/21 Python
java中如何截取字符串最后一位
2022/07/07 Java/Android