JavaScript的事件代理和委托实例分析


Posted in Javascript onMarch 25, 2015

在JavaScript中,经常会碰到要监听列表中多项li的情形,假设我们有一个列表如下:

<ul id="list">

  <li id="item1">item1</li>

  <li id="item2">item2</li>

  <li id="item3">item3</li>

  <li id="item4">item4</li>

</ul>

如果我们要实现以下功能:当鼠标点击某一li时,alert输出该li的内容,我们通常的写法是这样的:

当列表项比较少时,直接给每个li添加onclick事件
列表项比较多时,在onload时就给每个列表项调用监听
第一种方法比较简单直接,但是没有顾及到html与JavaScript的分离,不建议使用,第二种方法的代码如下:

window.onload=function(){

  var ulNode=document.getElementById("list");

  var liNodes=ulNode.childNodes||ulNode.children;

  for(var i=0;i<liNodes.length;i++){

    liNodes[i].addEventListener('click',function(e){

      alert(e.target.innerHTML);

    },false);

  }

}

由上可以看出来,假如不停的删除或添加li,则function()也要不停的更改操作,易出错,因此推荐使用事件代理,在使用事件代理之前,我们先来了解一下事件阶段(event phase):

事件阶段:

当一个DOM事件被触发的时候,他并不是只在它的起源对象上触发一次,而是会经历三个不同的阶段。简而言之:事件一开始从文档的根节点流向目标对象(捕获阶段),然后在目标对向上被触发(目标阶段),之后再回溯到文档的根节点(冒泡阶段)如图所示(图片来自W3C):

JavaScript的事件代理和委托实例分析

事件捕获阶段(Capture Phase)

事件的第一个阶段是捕获阶段。事件从文档的根节点出发,随着DOM树的结构向事件的目标节点流去。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达时间的目标节点。捕获阶段的主要任务是简历传播路径,在冒泡阶段,时间会通过这个路径回溯到文档根节点。

element.removeEventListener(<event-name>, <callback>, <use-capture>);

我们通过上面的这个函数来给节点设置监听,可以通过将;设置成true来为事件的捕获阶段添加监听回调函数。在实际应用中,我们并没有太多使用捕获阶段监听的用例,但是通过在捕获阶段对事件的处理,我们可以阻止类似click事件在某个特定元素上被触发。

var form=document.querySeletor('form');

form.addEventListener('click',function(e){

  e.stopPropagation();

  },true);

如果你对这种用法不是很了解的话,最好还是将设置为false或者undefined,从而在冒泡阶段对事件进行监听。

目标阶段(Target Phase)

当事件到达目标节点时,事件就进入了目标阶段。事件在目标节点上被触发,然后逆向回流,知道传播到最外层的文档节点。

对于多层嵌套的节点,鼠标和指针事件经常会被定位到最里层的元素上。假设,你在一个div元素上设置了click的监听函数,而用户点击在了这个div元素内部的p元素上,那么p元素就是这个时间的目标元素。事件冒泡让我们可以在这个div或者更上层的元素上监听click事件,并且时间传播过程中触发回调函数。

冒泡阶段(Bubble Phase)

事件在目标事件上触发后,并不在这个元素上终止。它会随着DOM树一层层向上冒泡,直到到达最外层的根节点。也就是说,同一事件会一次在目标节点的父节点,父节点的父节点...直到最外层的节点上触发。

绝大多数事件是会冒泡的,但并非所有的。具体可见:规范说明

由上我们可以想到,可以使用事件代理来实现对每一个li的监听。代码如下:

window.onload=function(){

  var ulNode=document.getElementById("list");

  ulNode.addEventListener('click',function(e){

       if(e.target&&e.target.nodeName.toUpperCase()=="LI"){/*判断目标事件是否为li*/

         alert(e.target.innerHTML);

       }

     },false);

};

以上所述就是本文的全部内容了,希望能够对大家熟悉javascript事件的委托和代理能够有所帮助。

请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持!

Javascript 相关文章推荐
Extjs列表详细信息窗口新建后自动加载解决方法
Apr 02 Javascript
jQuery获取样式中的背景颜色属性值/颜色值
Dec 17 Javascript
jquery选择器、属性设置用法经验总结
Sep 08 Javascript
jquery处理页面弹出层查询数据等待操作实例
Mar 25 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
Dec 10 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
Jun 24 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
Oct 09 Javascript
vue-cli 使用axios的操作方法及整合axios的多种方法
Sep 12 Javascript
angular 服务的单例模式(依赖注入模式下)详解
Oct 22 Javascript
在微信小程序中保存网络图片
Feb 12 Javascript
Vue学习笔记之计算属性与侦听器用法
Dec 07 Javascript
vue实现全屏滚动效果(非fullpage.js)
Mar 07 Javascript
JS实现简易图片轮播效果的方法
Mar 25 #Javascript
jquery处理页面弹出层查询数据等待操作实例
Mar 25 #Javascript
JavaScript动态添加列的方法
Mar 25 #Javascript
javascript实现复选框选中属性
Mar 25 #Javascript
jQuery的load()方法及其回调函数用法实例
Mar 25 #Javascript
jQuery使用$.get()方法从服务器文件载入数据实例
Mar 25 #Javascript
jQuery使用post方法提交数据实例
Mar 25 #Javascript
You might like
apache php模块整合操作指南
2012/11/16 PHP
header导出Excel应用示例
2014/01/24 PHP
PHPAnalysis中文分词类详解
2014/06/13 PHP
PHP中使用循环实现的金字塔图形
2014/11/08 PHP
PHP如何通过AJAX方式实现登录功能
2015/11/23 PHP
php中str_pad()函数用法分析
2017/03/28 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
js 数组操作代码集锦
2009/04/28 Javascript
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
基于jquery.Jcrop的头像编辑器
2010/03/01 Javascript
JS window对象的top、parent、opener含义介绍
2013/12/03 Javascript
jquery实现焦点图片随机切换效果的方法
2015/03/12 Javascript
js正则匹配出所有图片及图片地址src的方法
2015/06/08 Javascript
基于javascript实现样式清新图片轮播特效
2016/03/30 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
js基于setTimeout与setInterval实现多线程
2016/06/17 Javascript
Ionic 2 实现列表滑动删除按钮的方法
2017/01/22 Javascript
VUE 更好的 ajax 上传处理 axios.js实现代码
2017/05/10 Javascript
JS实现的计数排序与基数排序算法示例
2017/12/04 Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
2017/12/14 Javascript
基于vue框架手写一个notify插件实现通知功能的方法
2019/03/31 Javascript
对node通过fs模块判断文件是否是文件夹的实例讲解
2019/06/10 Javascript
jqGrid表格底部汇总、合计行footerrow处理
2019/08/21 Javascript
vue 实现在同一界面实现组件的动态添加和删除功能
2020/06/16 Javascript
详解uniapp的全局变量实现方式
2021/01/11 Javascript
[01:14:10]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Orenda
2014/05/22 DOTA
[01:14:31]Secret vs VG 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
Python网络编程详解
2017/10/31 Python
python 用户交互输入input的4种用法详解
2019/09/24 Python
波兰汽车配件网上商店:iParts.pl
2020/09/08 全球购物
如何掌握自荐信格式呢
2013/11/19 职场文书
大学生自我鉴定范文
2013/12/28 职场文书
童年读书笔记
2015/06/26 职场文书
机关干部作风整顿心得体会
2016/01/22 职场文书
描写九月优美句子(39条)
2019/09/11 职场文书
Fluentd搭建日志收集服务
2022/09/23 Servers