深入分析Javascript事件代理

很久很久以来,总感觉事件发生与事件代理到之间没什么鸟区别。

最近,又看了一下,感觉区别其实真不大!看怎么理解吧。

要搞清楚什么是事件代理,就需要先搞清楚什么是代理。

从商业角度来讲,代理就是:我有货,你没货,但丫我没时间、没精力全部卖掉,而你一天闲的蛋疼,只剩下时间了。于是,我委托你帮我买,然后哥给你提成。这个过程中,你实际上相当于也有了货。

OK,怎么从字面来理解事件代理一词的含义?后文有讲。

一 先看一个真实的,新手绑定onclik事件的例子

如果按照之前的我,我会怎么给每一个li标签,添加onlick呢?废话,要是我,肯定简单粗暴。
循环每一个li,然后全部绑定onlick。

于是我的代码应该是这样子:

<ul id="thl">
  <li>001</li>
  <li>002</li>
  <li>003</li>
</ul>

<script>
  var thl= document.getElementById('thl');
  var aLi = thl.getElementsByTagName('li');
  for (var i = 0; i < aLi.length; i++) {
    aLi[i].onclick = fn;
  }

  function fn (){
   console.log("maomaoliang");
  }
</script>

好像看起来没问题了。虽然,有些文章说这样很消耗性能,但是,我丫电脑好,老子管你性能,不能太认真。

二 突然有一天,我发现通过js添加进来的新的li,没有绑定onlcik

var node=document.createElement("li");
var textnode=document.createTextNode("maomaoliang");
node.appendChild(textnode);
document.getElementById("ul1").appendChild(node);

然后,点击maomaoliang,它并没有绑定我的onlick,这是为什么?
哦,原来,我原有的li跟我后面生成的li根本不是同时发生的,在创建新的li元素之前,已经给存在的li加事件了。好吧,好烦啊。

三 那怎么破?

然后,又好(无)奇(奈)的看了一些文章,原来有个叫事件代理的东西可以用。我就试试看吧!于是改写了部分代码,像这样:

var thl= document.getElementById('thl');
thl.onclick = function(ev) {
  ev = ev || event;
  //兼容处理
  var target = ev.target || ev.srcElement;
  //找到li元素
  if (target.nodeName.toLowerCase() == 'li') {
     fn();
   }
};

function fn (){
 console.log("maomaoliang");
}

结果,点击新的li,居然也触发了fn函数。好吧,身为一个好奇心驱动的肉身,我怎么能不求甚解呢?还是要踏实点,搞清楚这其中的奥秘才行。

于是,看了事件代理的资料。

首先,要知道什么是事件冒泡:当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡。

然后,再回到之前的问题“怎么从字面来理解事件代理一词的含义”,谁代理了事件?或者事件代理了谁?
以本文的例子来讲,看看改动后的代码,我把onlick事件绑定到了ul标签上面,而不是li标签。于是,当我点击任何一个li标签(不管是动态生成的还是之前就有的)是,这个事件就像泡泡一样,冒啊冒。正常的情况下,ul也会绑定onclick,body也会绑定到onclick,也就说它会冒泡到最根层的元素。但我这里给ul绑定了onlick,那么这时,ul会把泡泡截住,事件也就停止上升,无法抵达body标签。

接着, var target = ev.target || ev.srcElement;这一句话,相当于告诉了我,我究竟点的是谁,谁才是target。如果,这个target刚刚好就是li标签if (target.nodeName.toLowerCase() == 'li'),那么执行fn函数。

最后,我骄傲的回答了那个问题:table代理了onlick事件!

四 回忆一下事件代理的步骤

父元素绑定事件
父元素知道事件的实际发生目标是谁
我们要对目标进行判断,如果是我们需要的元素,则发生回调函数(所以要学好选择器的使用)

五 最后总结,事件代理两大好处

性能不小心得到了优化
动态添加的元素也能绑定事件了

六 需要注意的一点是

上述针对的是原生js事件绑定来讲的,如果你用到了jquery。并把代码改成了如下的样子:

/*var thl= document.getElementById('ul1');
thl.onclick = function(ev) {
  ev = ev || event;
  //兼容处理
  var target = ev.target || ev.srcElement;
  //找到li元素
  if (target.nodeName.toLowerCase() == 'li') {
     //li添加的事件
     fn();
   }
};*/

var node=document.createElement("li");
var textnode=document.createTextNode("maomaoliang");
node.appendChild(textnode);
document.getElementById("ul1").appendChild(node);

function fn (){
 console.log("maomaoliang");
}

$("#ul1").click(function(){
  fn();
});

这样一来,新添加的li标签,也能绑click,是不是很方便、很简单,是不是感觉学js没什么卵用。

哈哈,这样想很正常,我以前也这么想,但是,做了一些东西之后,发现jquery还真的不够用了!但是基本够用!

虽然,大神们都说要学js,但我还是觉得可以先学jquery,之后再学js,效果也可以的。

(0)

相关推荐

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

    在JavaScript中,经常会碰到要监听列表中多项li的情形,假设我们有一个列表如下: 复制代码 代码如下: <ul id="list">   <li id="item1">item1</li>   <li id="item2">item2</li>   <li id="item3">item3</li>   <li id="

  • JavaScript通过事件代理高亮显示表格行的方法

    本文实例讲述了JavaScript通过事件代理高亮显示表格行的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Highlight Rows</title> <style type

  • 浅析javascript中的事件代理

    本文的主要内容是根据前不久面试某家公司Web前端开发岗位,面试时做的一道数组去重问题的解题思路进行整理的,分享给大家. 题目本身很简单:一个ul中有一千个li,如何给这一千个li绑定一个鼠标点击事件,当鼠标点击时alert出这个li的内容和li的位置坐标xy, <ul id="ulItem"> <li id="li1">1</li> <li id="li2">2</li> <li

  • JavaScript事件代理和委托详解

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

  • 详解js的事件代理(委托)

    JavaScript事件代理(委托)一般用于以下情况: 1. 事件注册在祖先级元素上,代理其子级元素.可以减少事件注册数量,节约内存开销,提高性能. 2. 对js动态添加的子元素可自动绑定事件. 之前一直用各种js库的事件代理,如 jQuery,非常方便实用.今天尝试用原生 js 实现该功能. var addEvent = (function () { if (document.addEventListener) { return function (element, type, handler

  • javascript中的事件代理初探

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

  • 深入分析Javascript事件代理

    很久很久以来,总感觉事件发生与事件代理到之间没什么鸟区别. 最近,又看了一下,感觉区别其实真不大!看怎么理解吧. 要搞清楚什么是事件代理,就需要先搞清楚什么是代理. 从商业角度来讲,代理就是:我有货,你没货,但丫我没时间.没精力全部卖掉,而你一天闲的蛋疼,只剩下时间了.于是,我委托你帮我买,然后哥给你提成.这个过程中,你实际上相当于也有了货. OK,怎么从字面来理解事件代理一词的含义?后文有讲. 一 先看一个真实的,新手绑定onclik事件的例子 如果按照之前的我,我会怎么给每一个li标签,添加

  • 深入分析JavaScript 事件循环(Event Loop)

    事件循环(Event Loop),是每个JS开发者都会接触到的概念,但是刚接触时可能会存在各种疑惑. 众所周知,JS是单线程的,即同一时间只能运行一个任务.一般情况下这不会引发问题,但是如果我们有一个耗时较多的任务,我们必须等该任务执行完毕才能进入下一个任务,然而等待的这段时间常常让我们无法忍受,因为我们这段时间什么都不能做,包括页面也是锁死状态. 好在,时代在进步,浏览器向我们提供了JS引擎不具备的特性:Web API.Web API包括DOM API.定时器.HTTP请求等特性,可以帮助我们

  • JavaScript 事件代理需要注意的地方

    我们知道,如果给 form 里面的 button 元素绑定事件,需要考虑它是否会触发 form 的 submit 行为.除此之外,其它场合给 button 元素绑定事件,你几乎不用担心这个事件会有什么非预期的附加效果,很自然地会这样写事件处理代码: var button = document.querySelector('button') button.addEventListener('click', function (e) { console.log('点击了按钮') }) 你之所以放心这

  • JavaScript事件的委托(代理)的用法示例详解

    目录 简介 示例:事件委托 写法1:事件委托 写法2:每个子元素都绑定事件 示例:新增元素 写法1:事件委托 写法2:每个子元素都绑定事件 简介 说明 本文用示例介绍JavaScript中的事件(Event)的委托(代理)的用法. 事件委托简介 事件委托,也叫事件代理,是JavaScript中绑定事件的一种常用技巧.就是将原本需要绑定在子元素的响应事件委托给父元素或更外层元素,让外层元素担当事件监听的职务. 事件代理的原理是DOM元素的事件冒泡. 事件委托的优点 1.节省内存,减少事件的绑定 原

随机推荐