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 相关文章推荐
Firefox下提示illegal character并出现乱码的原因
Mar 25 Javascript
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
May 18 Javascript
一个可绑定数据源的jQuery数据表格插件
Jul 17 Javascript
js字符编码函数区别分析
Dec 28 Javascript
jquery提取元素里的纯文本不包含span等里的内容
Sep 30 Javascript
js实现全屏漂浮广告移入光标停止移动
Dec 02 Javascript
extjs 分页使用jsp传递数据示例
Jul 29 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
Jan 15 Javascript
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
Dec 14 Javascript
Angular中ng-bind和ng-model的区别实例详解
Apr 10 Javascript
vue-froala-wysiwyg 富文本编辑器功能
Sep 19 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
Oct 23 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
S900/ ETON E1-XM 收音机
2021/03/02 无线电
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
php查看当前Session的ID实例
2015/03/16 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
如何打开php的gd2库
2017/02/09 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
2019/04/03 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
Javascript之文件操作
2007/03/07 Javascript
几行代码轻松搞定jquery实现flash8类似的连接效果
2007/05/03 Javascript
Javascript数组的排序 sort()方法和reverse()方法
2012/06/04 Javascript
JavaScript中把数字转换为字符串的程序代码
2013/06/19 Javascript
Javascript Web Slider 焦点图示例源码
2013/10/10 Javascript
通过length属性判断jquery对象是否存在
2013/10/18 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
浅谈JavaScript 数据属性和访问器属性
2016/09/01 Javascript
jQuery设置图片等比例缩小的方法
2017/04/29 jQuery
Node.js使用Koa搭建 基础项目
2018/01/08 Javascript
vue addRoutes实现动态权限路由菜单的示例
2018/05/15 Javascript
彻底揭秘keep-alive原理(小结)
2019/05/05 Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
2020/05/13 Javascript
vue项目在线上服务器访问失败原因分析
2020/08/14 Javascript
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
Python中3种内建数据结构:列表、元组和字典
2014/11/30 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
2018/06/19 Python
python面向对象之类属性和类方法案例分析
2019/12/30 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
Python换行与不换行的输出实例
2020/02/19 Python
python单例模式的应用场景实例讲解
2021/02/24 Python
TripAdvisor印尼站:全球领先的旅游网站
2018/03/15 全球购物
单位领导证婚词
2014/01/14 职场文书
房地产广告词大全
2014/03/19 职场文书
大二学生自我检讨书
2014/10/23 职场文书
小学大队长竞选稿
2015/11/20 职场文书
世界文化遗产导游词
2019/08/07 职场文书
导游词之介休绵山
2019/12/31 职场文书