文档章节

JavaScript事件代理和委托详解(冒泡)

大头儿子程序猿
 大头儿子程序猿
发布于 2017/04/27 16:22
字数 973
阅读 6
收藏 0

JavaScript事件代理
事件代理在JS世界中一个非常有用也很有趣的功能。当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数。

这主要得益于浏览器的事件冒泡机制,下面我们具体举个例子来解释如何使用这个特性。

这个例子主要取自David Walsh的相关文章(How JavaScript Event Delegation Works)。

假设有一个 UL 的父节点,包含了很多个 Li 的子节点:

?

1

2

3

4

5

6

7

<ul id="list">

 <li id="li-1">Li 1</li>

 <li id="li-2">Li 2</li>

 <li id="li-3">Li 3</li>

 <li id="li-4">Li 4</li>

 <li id="li-5">Li 5</li>

</ul>

当我们的鼠标移到Li上的时候,需要获取此Li的相关信息并飘出悬浮窗以显示详细信息,或者当某个Li被点击的时候需要触发相应的处理事件。

我们通常的写法,是为每个Li都添加一些类似onMouseOver或者onClick之类的事件监听。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function addListenersLi(liElement) {

  liElement.onclick = function clickHandler() {

   //TODO

  };

  liElement.onmouseover = function mouseOverHandler() {

   //TODO

  }

 }

 

 window.onload = function() {

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

  var liElements = ulElement.getElementByTagName("Li");

   for (var i = liElements.length - 1; i >= 0; i--) {

    addListenersLi(liElements[i]);

   }

 }

如果这个UL中的Li子元素会频繁地添加或者删除,我们就需要在每次添加Li的时候都调用这个addListenersLi方法来为每个Li节点添加事件处理函数。

这会造成添加或者删除过程的复杂度和出错的可能性。

解决问题方法是使用事件代理机制,当事件被抛到更上层的父节点的时候,我们通过检查事件的目标对象(target)来判断并获取事件源Li。

下面的代码可以完成想要的效果: 

?

1

2

3

4

5

6

7

8

9

/ 获取父节点,并为它添加一个click事件

document.getElementById("list").addEventListener("click",function(e) {

 // 检查事件源e.targe是否为Li

 if(e.target && e.target.nodeName.toUpperCase == "LI") {

 //

 //TODO

 console.log("List item ",e.target.id," was clicked!");

 }

});

 

在原生js中 event需要做兼容性处理

var e=window.event || e;

var target=e.target || e.srcElement;

为父节点添加一个click事件,当子节点被点击的时候,click事件会从子节点开始向上冒泡。父节点捕获到事件之后,通过判断e.target.nodeName来判断是否为我们需要处理的节点。并且通过e.target拿到了被点击的Li节点。从而可以获取到相应的信息,并作处理。

事件冒泡及捕获
浏览器的事件冒泡机制,对于事件的捕获和处理,不同的浏览器厂商有不同的处理机制,这里介绍W3C对DOM2.0定义的标准事件。

DOM2.0模型将事件处理流程分为三个阶段:

一、事件捕获阶段,

二、事件目标阶段,

三、事件起泡阶段。

如下图:

事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。

本文转载自:http://www.jb51.net/article/82099.htm

共有 人打赏支持
大头儿子程序猿
粉丝 0
博文 20
码字总数 3454
作品 0
奉贤
程序员
私信 提问
彻底弄懂JS事件委托的概念和作用

一、写在前头 接到某厂电话问什么是事件代理的时候,一开始说addEventListener,然后他说直接绑定新的元素不会报dom不存在的错误吗?然后我就混乱了,我印象中这个方法是可以绑定新节点的。后面...

xiaobiB
2018/08/18
0
0
js中的事件委托或是事件代理详解

起因: 1、这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的; 2、其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考; 概述: 那什么...

菜鸟的进阶
2017/10/22
0
0
前端面试之JavaScript

1. JS基本的数据类型和引用类型 基本数据类型:number、string、null、undefined、boolean、symbol -- 栈 引用数据类型:object、array、function -- 堆 两种数据类型存储位置不同 原始数据类...

大灰狼的小绵羊哥哥
2018/08/27
0
0
《高性能javascript》 领悟随笔之-------DOM编程篇(二)

《高性能javascript》 领悟随笔之-------DOM编程篇二   序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整个页面文档。DOM编程性能一直以来都...

grootzhang
2016/05/10
0
0
JS和JQ的event对象对比和应用

currentTarget 事件冒泡阶段所在的DOM target, originalTarget原始的DOM 代码测试: 结果分析: 总结: js的event参数中,不管是, , 都是指向第一个触发事件的元素(还没冒泡),而在click事...

前端届的科比
2014/08/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

都996了,研发效能还是提不出起来,关键在这里

本文作者:何勉 上一篇我们介绍了研发效能提升目标及其度量方法。(本文是阿里“研发效能提升系列”的第2篇,第1篇“研发效能的定义和度量”敬请期待 研发效能的提升必须落实为团队需求、协作...

阿里云云栖社区
16分钟前
1
0
阿里高级技术专家:研发效能的追求永无止境

背景 大约在5年前,也就是2013年我刚加入阿里的时候,那个时候 DevOps 的风刚吹起来没多久,有家公司宣称能够一天发布几十上百次,这意味着相比传统软件公司几周一次的发布来说,他们响应商业...

zhaowei121
26分钟前
2
0
深度解读 | 等保2.0之移动互联安全扩展要求解读

数字经济下,企业的生态核心是应用为核心。随着移动互联网的发展,移动应用已渗透各行各业,与工作、生活息息相关。工信部发布的数据显示,截至2018年8月底,我国市场上监测到的移动应用App...

工作的事
33分钟前
0
0
垃圾收集器

1、哪些内存需要回收? 2、什么时候回收? 3、如何回收? "自动回收" 当需要排查各种内存溢出、内存泄露问题时 当垃圾集成为系统达到更高并发量的瓶颈时 引用计数算法 假设方案一:给对象中添...

恋码之子
33分钟前
1
0
独家解密:阿里大规模数据中心性能分析

郭健美,阿里巴巴高级技术专家,目前主要从事数据中心的性能分析和软硬件结合的性能优化。CCF 系统软件专委和软件工程专委的委员。曾主持国家自然科学基金面上项目、入选上海市浦江人才计划A...

阿里云官方博客
34分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部