在了解什么是DOM事件以及给DOM事件绑定监听器的几种方法后,我们来谈谈事件委托。
1. e.target 和 e.currentTarget
当我们给目标元素target 绑定一个事件监听器target.addEventListener(event,function(){}), 并指定回调函数function(e), 函数的参数e表示事件。此时e.target 与 e.currentTarget分别表示自己触发事件的元素与被监听的元素
<html>
<body>
<ul style='list-style:none;max-width:200px;border:1px solid;'>
<li>点我试试</li>
<ul>
<script>
(document.querySelector('ul')).addEventListener('click' ,function(e){
console.log('e.target')
console.log(e.target)
console.log('e.currentTarget')
console.log(e.currentTarget)
})
</script>
</body>
</html>
x
 
1
<html>
2
<body>
3
<ul style='list-style:none;max-width:200px;border:1px solid;'>
4
  <li>点我试试</li>
5
<ul>
6
<script>
7
  (document.querySelector('ul')).addEventListener('click' ,function(e){
8
    console.log('e.target')
9
    console.log(e.target)
10
    console.log('e.currentTarget')
11
    console.log(e.currentTarget)
12
  })
13
  </script>
14
</body>
15
</html>
16

这段代码为一个ul元素绑定了一个监听器,当ul上发生点击事件时,分别输出e.target和e.currentTarget的值。
当点击ul中的li元素时,该段代码的在控制台输出的结果如下:
此时,e.target为直接点击的元素li,而e.currentTarget为被监听的元素ul。由此我们可以得到一个启发,触发事件的元素与被监听的元素不一定是一个元素。于是就来到了本文的重点内容——事件委托。
2. 如何进行事件委托
  什么情况下回用到事件委托呢?举两个例子
1) 当存在多个元素可以共用同一个监听器
<body>
<ul>
<li>点<span>这里</span></li>
<li>点这里</li>
</ul>
<style>
ul, li{
list-style:none;
border:1px solid;
padding:10px;
background:#ddd
}
li{
text-align:center;
margin:10px;
background:#fff
}
</style>
</body>
</html>
x
 
1
<body>
2
<ul>
3
  <li>点<span>这里</span></li>
4
  <li>点这里</li>
5
</ul>
6
<style>
7
  ul, li{
8
  list-style:none;
9
  border:1px solid;
10
  padding:10px;
11
  background:#ddd
12
}
13
li{
14
  text-align:center;
15
  margin:10px;
16
  background:#fff
17
}
18
</style>
19
</body>
20
</html>
21

上面的代码中定义了如图所示的一个ul,它包裹着两个li,第一个li中还有一个子元素span。如果我们希望点击两个li均执行同一条命令时,第一种方法是为每个li都绑定一个监听器,但当li很多时,这样处理就过于繁琐。
这时我们会想到可以直接监听ul,为ul绑定事件函数,那么只要li存在于ul的内部,点击任意的一个li都会执行这条命令。但同样存在一个问题,当点击li的外部,也就是图中的灰色区域时,命令同样会被执行。
那么如何仅仅在点击li的覆盖区域的时候才执行这段命令呢,可以用以下这段代码。
var ul=document.querySelector('ul')
ul.addEventListener('click',function(e){
var el = e.target
//判断当前点击的元素是否为li,如果不是,执行以下的while循环
while(el.tagName !== 'LI'){
//如果点击的元素为ul,直接跳出循环
if(el === ul){
el = null
break;
}
//否则,将当前元素父元素赋给el
el=el.parentNode
}
//如果最后el不为null,则打出'ok'
if(el){
console.log('ok')
}
//否则,打出'你点击的不是li'
else console.log('你点击的不是li')
})
x
 
1
var ul=document.querySelector('ul')
2
ul.addEventListener('click',function(e){
3
  var el = e.target
4
//判断当前点击的元素是否为li,如果不是,执行以下的while循环
5
  while(el.tagName !== 'LI'){
6
//如果点击的元素为ul,直接跳出循环
7
    if(el === ul){
8
      el = null
9
      break;
10
    }
11
//否则,将当前元素父元素赋给el
12
      el=el.parentNode
13
  }
14
//如果最后el不为null,则打出'ok'
15
  if(el){
16
    console.log('ok')
17
  }
18
//否则,打出'你点击的不是li'
19
  else console.log('你点击的不是li')
20
})
21

这段代码实现了当点击的区域在li范围内时,不管点击的是li元素本身,还是li的子元素span,都会执行console.log('ok'),但当点击区域超出li的范围,则执行' console.log('你点击的不是li')'。这就成功实现了一个事件委托。
(2) 用事件委托实现动态监控
还有一种情况,也会用到事件委托,那就是需要动态监控的时候。
看以下代码:
<html>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<button id=addButton>+</button>
</body>
</html>
<style>
li{
border: 1px solid;
}
</style>
<script>
addButton.onclick = function(){
var li = document.createElement('li')
li.textContent = 'new'
document.querySelector('ul').appendChild(li)
}
document.querySelector('ul').onclick = function(e){
console.log(e.target)
}
</script>
</body>
</html>
x
 
1
<html>
2
<body>
3
<ul>
4
  <li>1</li>
5
  <li>2</li>
6
  <li>3</li>
7
  <li>4</li>
8
</ul>
9
  <button id=addButton>+</button>
10
</body>
11
</html>
12
<style>
13
li{
14
  border: 1px solid;
15
}
16
</style>
17
<script>
18
addButton.onclick = function(){
19
  var li = document.createElement('li')
20
  li.textContent = 'new' 
21
  document.querySelector('ul').appendChild(li)
22
}
23
document.querySelector('ul').onclick = function(e){
24
  console.log(e.target)
25
}
26
</script>
27
</body>
28
</html>
29

这段代码实现的效果如下:
当点击左下角的加号按钮时,会增加一个新的li,同时在点击li时,在控制台输出被点击的li的内容。这就是用事件委托实现动态监控。

javascript举例介绍事件委托的典型使用场景的更多相关文章

  1. js实例分析JavaScript中的事件委托和事件绑定

    我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...

  2. JavaScript中的事件委托(转至大佬)

    转至:https://www.cnblogs.com/liugang-vip/p/5616484.html 起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没 ...

  3. JavaScript中的事件委托机制跟深浅拷贝

    今天聊下JavaScript中的事件委托跟深浅拷贝 事件委托 首先呢,介绍一下事件绑定 //方法一:通过onclick <button onclick="clickEvent()&qu ...

  4. 简单说 JavaScript中的事件委托(下)

    说明 上次我们说了一些,关于 JavaScript中事件委托的 基础知识,这次我们继续来看. 解释 先来一段代码 <!doctype html> <html lang="e ...

  5. javascript中的事件委托

    这几天看到一个面试题,大概就是,让你给1000个li都添加一个click事件,应该怎么添加?大多数人第一开始的感觉可能就是,每个li上边都添加一个呗,那要是这样的话,估计面试的时候就会GG了,这里就是 ...

  6. Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制

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

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

    原:http://www.jb51.net/article/93752.htm 在JavaScript的学习中,我们经常会遇到JavaScript的事件机制,例如,事件绑定.事件监听.事件委托(事件代 ...

  8. JavaScript事件代理和事件委托

    一.概述: 那什么叫事件委托呢?它还有一个名字叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件.那这是什么意思呢?网上的 ...

  9. javascript事件委托和jquery事件委托

    元旦过后,新年第一篇. 初衷:很多的面试都会涉及到事件委托,前前后后也看过好多博文,写的都很不错,写的各有千秋,自己思前想后,为了以后自己的查看,也同时为现在找工作的前端小伙伴提供一个看似更全方位的解 ...

随机推荐

  1. DataTable记录

    DataTable dt2 = dt.Copy();//复制结构和数据 //复制结构,不要数据 DataTable dt2 = new DataTable(); for (int i = 0; i & ...

  2. Java字符串split分割星号*等特殊字符问题(转)

    Java的split()方法分割字符串比较常用(见[Java]字符串以某特殊字符分割处理 ),但在有的时候,会遇到星号*等正则表达式中的特殊字符而无法分割的问题. 比如某需求,用户输入产品规格:厚*宽 ...

  3. css控制同一个页面的两个表格,一个显示有边框线,而另一个没边框线

    不显示边框的:<table border="0" cellspacing="0"  cellpadding="" ><tr ...

  4. Lamda表达式,map和集合操作

    1.Lamda表达式,map快速获取对象的某一个属性生成集合 List<String> elementSlugs = elementInstanceBOList.stream().map( ...

  5. Linux umask权限

    文件基本权限 Linux中文件权限由三部分组成: rw-r--r-- 前三位:表示用户所拥有的权限 中三位:表示用户所在组的权限 后三们:表示其他用户的权限 权限 八进制 十进制 - - - 000 ...

  6. Zabbix部署与使用

    *******需要配置网易YUM源来安装相关依赖包: [local_yum] name=local_yum baseurl=http://mirrors.163.com/centos/6/os/x86 ...

  7. CAS实战の自定义登录

    由于每个版本的改动较大,所以先把版本号列出: 服务端版本:cas server 4.0.0 客户端版本:cas client 3.3.3 一.自定义登录页面 页面路径:/WebContent/WEB- ...

  8. 咏南中间件新增SQL日志

    为了方便开发时跟踪调试SQL语句的执行情况,咏南中间件新增SQL日志,所有执行过的SQL都会写入SQL日志文件中. SQLDEBUG设为1,启用:设为0,停止写SQL日志.

  9. 解决json结合struts2时,Class org.apache.struts2.json.JSONWriter can not access a member of * 的问题

    在使用json的时候,产生的一个错误,查了一下资料,原来是struts2和json一起使用的时候,才产生的问题,虽然不影响程序的运行,但是总是会有一些异常的日志产生,并且,这个也会增加程序的负担. 原 ...

  10. vim 命令全

    1 简介 vim是文本编辑器.代码补完.编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用.下面讲述一些必要的基本命令,而掌握好这些命令,您就能够很容易将vim当作一个通用的万能编辑器来使用 ...