在了解什么是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. jdeveloper 恢复默认配置

    1>jdeveloper的环境设置出现问题,恢复默认的配置,需要删除保存再登录账户中的配置文件,以达到恢复默认配置的目的.只需删除以下配置文件目录即可. C:\Users\当前登录用户名\App ...

  2. C# 与 Java Rsa加密与解密互通

    Rsa 加密标准的制定已经过去了十多年了. 这两天在看rsa 加密的文章,基本上都是在说 .net 与 java 之间的 rsa加密是不能互通的.因为项目有用到,所以花了点时间对rsa加密做了一点点了 ...

  3. MVC DbContext

    指定数据连接,指定表名,移除表名复数化(表名后面不加s),设置字段约束,主外键关系. using MvcApplication1.Models; using System; using System. ...

  4. [Training Video - 5] [Groovy Script Test Step - Collections, Exceptions] HashSet and Hashtable

    Hashset: HashSet set = new HashSet() set.add("India") set.add("USA") set.add(&qu ...

  5. 一起做RGB-D SLAM(8) (关于调试与补充内容)

    “一起做”系列完结后,我收到不少同学给我的反馈.他们提了一些在程序编译/运行过程中的问题.我把它们汇总起来,组成了这个“补充篇”.你也可以看成是一个Q&A. Q: OpenCV的版本?A: 我 ...

  6. 使用js/jquery查找iframe中的

    原生js  一.在iframe的父窗口中获取iframe中的元素: js代码 格式: window.frames["iframe的name值"].document.getEleme ...

  7. python使用git进行版本控制-分支管理

    1.远程克隆 最好的方式是先创建远程库,然后,从远程库克隆: 首先在github上创建一个新的仓库,名字叫gitskills 我们勾选Initialize this repository with a ...

  8. require的路径问题(比较重要)

    dojo.baseUrl baseUrl用来存储dojo.js存放 的跟目录,例如dojo.js的路径是“/web/scripts/dojo-1.3/dojo/dojo.js”则baseUrl为“/w ...

  9. JAVA内存管理再解

    首先我们要明白一点,我们所使用的变量就是一块一块的内存空间!!   一.内存管理原理:   在java中,有java程序.虚拟机.操作系统三个层次,其中java程序与虚拟机交互,而虚拟机与操作系统间交 ...

  10. 2、Docker和虚拟机的对比

    2.1 虚拟化技术   虚拟机Virtual Machine与容器化技术(代表Docker)都是虚拟化技术,两者的区别在于虚拟化的程度不同.   Docker为代表的容器化技术并不是虚拟机.   虚拟 ...