资讯专栏INFORMATION COLUMN

事件冒泡机制与委托机制

AprilJ / 1400人阅读

摘要:二事件委托机制知道了事件的捕获冒泡机制,我们可以利用它来实现更方便的程序控制,事件委托便是最典型的应用之一。下面来说说中的事件委托机制。

一、事件的捕获与冒泡

   由W3C规定的DOM2标准中,一次事件的完整过程包括三步:捕获→执行目标元素的监听函数→冒泡,在捕获和冒泡阶段,会依次检查途径的每个节点,如果该节点注册了相应的监听函数,则执行监听函数。以下面的HTML结构为例:

父亲
孩子

  执行的流程应该是这样的:

  下面是一组例子,分别点击孩子节点可以清楚的看到第三个参数的影响:

父亲

孩子

父亲节点的监听函数在捕获阶段执行:

var parent1 = document.getElementById(‘parentdiv1′);
var child1 = document.getElementById(‘childdiv1′);
parent.addEventListener(‘click’,function(){alert(‘父亲被点击了’);},true);//第三个参数为true
child.addEventListener(‘click’,function(){alert(‘孩子被点击了’);},false);

父亲

孩子
父亲节点的监听函数在冒泡阶段执行:

var parent2 = document.getElementById(‘parentdiv2′);
var child2 = document.getElementById(‘childdiv2′);
parent.addEventListener(‘click’,function(){alert(‘父亲被点击了’);},false);//第三个参数为false
child.addEventListener(‘click’,function(){alert(‘孩子被点击了’);},false);

父亲

孩子

父亲节点的监听函数在捕获冒泡阶段都执行:

var child3 = document.getElementById(‘childdiv3′);
parent.addEventListener(‘click’,function(){alert(‘父亲被点击了’);},true);//第三个参数为true
parent.addEventListener(‘click’,function(){alert(‘父亲被点击了’);},false);//第三个参数为false
child.addEventListener(‘click’,function(){alert(‘孩子被点击了’);},false);

  如果不想让事件向上冒泡,可以在监听函数中调用event.stopPrapagation()来完成,这样父亲节点就捕捉不到该事件了。在实际的开发中,这一用处还是挺多的。

二、事件委托机制

       知道了事件的捕获冒泡机制,我们可以利用它来实现更方便的程序控制,事件委托便是最典型的应用之一。下面来说说javascript中的事件委托机制。什么叫委托呢?想想我们现实生活中,自己不想干的事,让别人来帮忙完成,这就是把事情“委托”给别人。Javascript的事件委托机制也是这个道理,本来一个监听函数要处理节点a触发的事件,现在把这个监听函数绑定到节点a的父层节点上,让它的父辈来完成事件的监听,这样就把事情“委托”了过去。在父辈元素的监听函数中,可通过event.target属性拿到触发事件的原始元素,然后再对其进行相关处理。

       那这样做有什么好处呢?最大的用处便是监听动态增加的元素。比如我们现在有这样的需求,点击下面每个列表项弹出各自的内容,现在随着web应用的盛行,网页中使用异步请求来动态加载节点已经变的很普遍,所以我们点击下方的按钮要在列表中增加一项,并且点击新增加的节点也要弹出内容。HTML结构如下:

  1. 列表内容1
  2. 列表内容2
  3. 列表内容3
  4. 列表内容4
  5. 列表内容5

  若我们使用之前的监听器绑定方式,需要遍历所有的li元素并监听,代码应该是这样的:

var listArray = document.getElementById("olist").childNodes;
for(var i=0;i

  运行效果如下:

列表内容1

列表内容2

列表内容3

列表内容4

列表内容5

  可以发现当新增元素后,点击它并没有弹出内容。那是当然的了,因为我们并没有给新增的元素绑定监听器,为了实现点击新增元素也弹出内容,我们不得不在每次新增一个元素后,再进行一次绑定。加一个绑一个,加一个绑一个,累不累啊!你不累浏览器都累了!这样做导致的性能开销是可想而知的,而且浏览器还要维系n多元素与应的监听函数的映射关系,会占用大量内存。

       面对这样拖沓冗杂的代码,你是不是已经不能忍,来看看使用事件委托的效果,代码如下:

var olist = document.getElementById("olist");
olist.addEventListener("click",function(){
    alert(event.target.innerText);
},false);

  看看实际运行的效果:

列表内容1

列表内容2

列表内容3

列表内容4

列表内容5

  我们并未给li元素绑定任何监听器,而是监听它的父元素ul,等到事件冒泡上来的时候,在处理函数中通过event.target获得触发事件的li元素,进行相关处理。这样做的好处是显而易见的,首先只进行了一次监听器的绑定,浏览器轻松,其次动态增加元素后你也不必要再绑定监听器,你也轻松。正所谓大家好才是真的好!

       本篇的基本内容就介绍完了,你是不是感觉有点奇妙,我平时写程序的时候没关心这些也仍然能完成工作呀?那我就得问你是不是使用js框架,使用jQuery了,事实上,jQuery提供的on、live等方法就已经对事件委托进行了封装,为委托机制的推广悄悄做了底层贡献,你没感觉到而已。jQuery中的各种事件监听方式也需要我们有一个清楚的了解,才能正确的使用,高效的完成工作。这些内容将放在下一篇介绍。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79576.html

相关文章

  • 事件委托冒泡机制有关系吗?

    摘要:等等,挺在这里,虽然不仅一篇文章阐述了事件委托是利用了冒泡机制,得益于冒泡机制,但是,怎么得益的,怎么利用的。事件委托和冒泡机制有关系吗接下来我想引出本文的重点事件委托和冒泡机制有关系吗我认为就算有关系,关系也不大。 面试官提出的问题 我们在面试前端的过程中,经常会听到面试官问这样的问题: 如果我有一个页面,里面1000个元素都要绑定click事件,请问你要怎么做 如果你...

    joywek 评论0 收藏0
  • 简单聊聊浏览器JS事件触发机制

    摘要:事件冒泡由微软提出,事件会从最内从的元素开始发生,再向外传播,正好与事件捕获相反。为了解决上述问题,我们可以利用事件委托的思想,在父级注册一个事件监听器,统一进行子元素的事件处理。 原理 事件捕获 由网景最先提出,事件会从最外层开始发生,直到最具体的元素,也就是说假如父元素与子元素都绑定有点击事件,又互相重叠,那么先出发的会是父元素的事件,然后再传递到子元素。 事件冒泡 由微软提出,事...

    enrecul101 评论0 收藏0
  • JS专题之事件模型

    摘要:三事件流规定事件包括三个阶段,事件捕获,处于目标阶段事件冒泡。一起来看添加新增加的,点击发现没有反应,说明事件没有绑定进去,但是我们也并不想,每增加一个新元素,就为这个新元素绑定事件,重复低效率的工作应当避免去做。 本文共 1960 字,读完只需 8 分钟 事件 用户与网页交互是通过事件实现的,事件刚开始是作为分担服务器负载的一个手段,起初没有统一的规范,直到 DOM2 级,网景和 I...

    W4n9Hu1 评论0 收藏0
  • 浅谈事件委托机制

    摘要:所谓的事件委托,简单的来说就是将一个元素响应事件委托给另外一个元素。而正好浏览器当中有事件冒泡机制,一张图简单了解下浏览器的事件响应机制。 适用场景 在日常开发过程中,我们经常会遇到这样一种场景:我需要通过ajax从后端获取数据后动态添加dom节点来展示数据,并且这些dom节点有时候又需要是可交互的,例如点击事件。那么在我们获取到数据之前这些dom节点是不存在的,也就是说我们没办法在获...

    WelliJhon 评论0 收藏0
  • 事件委托冒泡机制

    摘要:概念事件委托,就是某个事件本来该自己干的,但是自己不干,交给别人来干。冒泡机制,就是父节点监控着一块区域的点击事件,当点击事件触发时,会根据坐标来判断是哪一块区域被点击,然后确定事件对象的属性或者说是属性。 概念 事件委托,就是某个事件本来该自己干的,但是自己不干,交给别人来干。就叫事件委托。打个比方:一个button对象,本来自己需要监控自身的点击事件,但是自己不来监控这个点击事...

    warmcheng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<