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

在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):

事件捕获阶段(Capture Phase)

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

代码如下:

element.removeEventListener(&ltevent-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事件的委托和代理能够有所帮助。

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

(0)

相关推荐

  • JavaScript中的事件委托及好处

    1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件. 也就是:利用冒泡的原理,把事件加到父级上,触发执行效果. 好处呢:1,提高性能. 我们可以看一个例子:需要触发每个li来改变他们的背景颜色. <ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb&l

  • JavaScript事件委托的技术原理探讨示例

    如今的JavaScript技术界里最火热的一项技术应该是'事件委托(event delegation)'了.使用事件委托技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器是被添加到它们的父元素上.事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件.基本概念非常简单,但仍有很多人不理解事件委托的工作原理.这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子. 假定我们有一个UL元素,它有几个子元素: 复制代码 代码如下: <ul id=&qu

  • js事件委托和事件代理案例分享

    什么是事件委托/事件代理 利用事件的冒泡传播机制(触发当前元素的某一个行为,它父级所有元素的相关行为都会被触发),如果一个容器中有很多元素都要绑定点击事件,我们没有必要一个个的绑定了,只需要给最外层容器绑定一个点击事件即可,在这个方法执行的时候,通过事件源的区分来进行不同的操作. 具体小案例如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

  • JavaScript事件代理和委托详解

    在javasript中,代理.委托经常出现. 那么它究竟在什么样的情况下使用?它的原理又是什么? 这里介绍一下javascript delegate的用法和原理,以及Dojo,jQuery等框架中delegate的接口. JavaScript事件代理 事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委托给父节点来触发处理函数. 这主要得益于浏览器的事件冒泡机制,下面我们具体举个例子来解释如何使用这个特性. 这个例子主要取

  • javascript中的事件代理初探

    事件在javascript中一直是最强大的对象之一.javascript提供了addEventListener和attachEvent两个方法来为DOM节点绑定事件,jquery作了进一步封装,提供了兼容各个浏览器的bind方法.现在来看,这种传统的事件绑定方式存在着以下不足: 1.可能需要绑定很多的EventHander. 假如页面中某个表有100行,现在必须为每一行绑定一个click事件.那么就必须绑定100个EventHandler,这对页面性能来说有着极大的负担,因为需要创建更多的内存来

  • javascript性能优化之事件委托实例详解

    本文实例分析了javascript性能优化之事件委托.分享给大家供大家参考,具体如下: 为下面每个LI绑定一个click事件 <ul id="myLinks"> <li id="goSomewhere" >Go somewhere</li> <li id="doSomething" >Do something</li> <li id="sayHi" >Sa

  • JS 事件绑定、事件监听、事件委托详细介绍

    在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定.事件监听.事件委托(事件代理)等.这些名词是什么意思呢,有什么作用呢? 事件绑定 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数.所谓事件处理函数,就是处理用户操作的函数,不同的操作对应不同的名称. 在JavaScript中,有三种常用的绑定事件的方法: 在DOM元素中直接绑定: 在JavaScript代码中绑定: 绑定事件监听函数. 在DOM中直接绑定事件

  • JavaScript事件委托用法分析

    本文实例讲述了JavaScript事件委托用法.分享给大家供大家参考.具体分析如下: 一.点击页面任何部分触发事件 创建一个script1.js文件. 复制代码 代码如下: (function() {     eventUtility.addEvent(document, "click", function(evt) {         alert('hello');     }); }()); 页面部分. 复制代码 代码如下: <head> <meta http-e

  • javascript事件委托的方式绑定详解

    js事件绑定 事件绑定,这里使用了冒泡的原理,从点击的元素开始,递归方式的向父元素传播事件,这样做的好处是对于大量要处理的元素,不必为每个元素都绑定事件,只需要在他们的父元素上绑定一次即可,提高性能.还有一个好处就是可以处理动态插入dom中的元素,直接绑定的方式是不行的. 之前一直使用的是jquery的on方法做这样的事情,前几天看到公司项目中有实现这种方式的源代码,拿来仔细研究研究,跟大家分享分享. function $bindAction(dom, event, listeners) { #

  • JavaScript事件委托技术实例分析

    本文实例分析了JavaScript事件委托技术.分享给大家供大家参考.具体分析如下: 如果一个整体页面里有大量的按钮.我们就要为每一个按钮绑定事件处理程序.这样就会影响性能了. 首先每个函数都是对象,对象就会占用很多内存.内存中的对象越多,性能就越差. 其次,dom访问次数增多,就会导致延迟加载页面.事实上,从如何来利用好事件处理程序,还是有很好的解决方案的. 事件委托: 对事件处理程序过多的问题解决的方案就是事件委托技术. 事件委托技术利用了事件冒泡.只需指定一个事件处理程序. 我们可以为某个

随机推荐