美文网首页
JS中的事件代理详解

JS中的事件代理详解

作者: 呗儿塔 | 来源:发表于2019-01-25 04:45 被阅读0次
事件代理的定义

对于事件委托或者说事件代理,有这样一段定义:

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

举个例子来说
首先我们创建一个拥有多个平行元素的列表

<ul id="parent-list">  
  <li id="post-1">Item 1</li>   
  <li id="post-2">Item 2</li>   
  <li id="post-3">Item 3</li>   
  <li id="post-4">Item 4</li>   
  <li id="post-5">Item 5</li>   
  <li id="post-6">Item 6</li> 
</ul>  

当鼠标移动到li上或者点击了li的时候,需要触发相应的事件,若果不使用事件代理,那么我们需要为每一个li都添加相应的 onClick()或者 onMouseOver()事件,代码如下:

function addListeners4Li(liNode) {
 liNode.onclick = function clickHandler(){alert('Click')};     
 liNode.onmouseover = function mouseOverHandler(){alert('MouseOver')} 
}

window.onload = function(){
  var ulNode = document.getElementById("parent-list"); 
  var liNodes = ulNode.getElementByTagName("Li"); //获取所有li节点
  for(var i=0, l = liNodes.length; i < l; i++){    
    addListeners4Li(liNodes[i]); //为每一个li节点添加监听
 }

这种方法的缺点在于

  1. 由于在javascript中,每一个函数都是一个对象,是对象就会占用内存,对象越多,占用的内存也就越大,在上面的方法中,我们创建了6个 liNodes对象,对每一个对象进行监听,但是如果li的数量特别庞大时,这种方法其实是很占用内存的
  2. 在上面的方法中,我们对每一个 liNodes对象都添加了监听,而在javascript中,添加到页面中的事件处理程序数量将直接影响程页面的整体性能,因为事件处理程序越多,与dom交互的次数就越多,引起浏览器重绘与重排的次数也就越多,从而拖慢页面的就绪时间。
  3. 如果我们需要频繁的删除和添加 li元素,就需要在每一次添加时都为其绑定事件,过于繁琐。

总结一下就是:

**1. 创建的js对象过多,占用内存

  1. JS与DOM之间的关联过多,影响性能,容易造成内存泄漏
  2. 需要管理的函数过多,对于每个元素都要添加监听**

使用事件代理可以很好的解决这两个问题,但在我们介绍事件代理之前,先要说一下事件的冒泡机制


事件的冒泡及捕获

不同的浏览器对于事件的冒泡及捕获有不同的处理方式,这里主要介绍W3C对DOM2.0定义的标准事件:

图片.png

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

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

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

其中 addEventListener(eventType,callBack,true | false)函数的第三个属性为 useCapture这个属性默认为 false意为在事件冒泡阶段调用事件处理函数,如果为 true则是在事件捕获阶段调用事件处理函数。


事件代理的使用

对于上面的代码,我们可以使用事件代理来进行简化,只对平行元素共同的父元素进行监听,根据其获取的源事件属性,来做出相应的处理:

document.getElementById("parent-list").addEventListener("click",function(e) { 
  //检查事件源的属性
  if(e.target && e.target.nodeName.toUpperCase == "LI") { 
    console.log("List item ",e.target.id.replace("post-")," was clicked!"); 
  }
}

在上述代码中,在 click()事件的毁掉函数中有一个源事件 e,通过查看源事件中的属性,我们可以确定当前事件是从哪个元素触发的,从而做出相应的Actions

参考:
浅析JavaScript的事件代理和委托
js中的事件委托或是事件代理详解

相关文章

  • JS写事件代理

    js中的事件委托或是事件代理详解

  • JS中的事件代理详解

    事件代理的定义 对于事件委托或者说事件代理,有这样一段定义: 事件委托就是利用事件冒泡,只指定一个事件处理程序,就...

  • 事件委托

    还有很多要学,要加油哇。回正题。参考: js中的事件委托或是事件代理详解 1、基本概念事件委托就是利用事件冒泡,只...

  • 2018-06-27

    js中的事件委托或是事件代理详解 起因: 1、这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的; 2、其...

  • 什么是事件委托

    js中的事件委托或是事件代理详解 起因: 1、这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的; 2、其...

  • js中的事件委托或是事件代理详解

    起因: 1、这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的; 2、其实我一直都没弄明白,写这个一是为了...

  • js中的事件委托或是事件代理详解

    转载自https://www.cnblogs.com/liugang-vip/p/5616484.html 起因:...

  • js中的事件委托或是事件代理详解

    https://www.cnblogs.com/liugang-vip/p/5616484.html

  • js中的事件委托或是事件代理详解

    1、前言 : 本篇文章完全出自 凌云之翼(链接) 的博客。 2、概述 什么叫事件委托呢?它还有一个名字叫事件代理,...

  • JavaScript的事件机制详解

    【js事件详解】js事件封装函数,js跨浏览器事件处理机制 一、事件流 事件流描述的是从页面中接受事件的顺序。IE...

网友评论

      本文标题:JS中的事件代理详解

      本文链接:https://www.haomeiwen.com/subject/iavpjqtx.html