什么是事件委托(代理)?

前置知识

事件冒泡 && 事件捕获

当我们触发一个元素事件时,如果事件从最内层元素传递到最外层元素,此过程为事件冒泡,如果从最外层元素传递到最内层元素,此过程为事件捕获

如以下代码所示:

  • 若触发事件冒泡,则事件执行顺序为cba
  • 若触发事件捕获,则事件执行顺序为abc
1
2
3
4
5
6
<div class="a">
<div class="b">
<div class="c">
</div>
</div>
</div>

Javascript中addEventListener为元素绑定事件的方法,它接收三个参数

  1. event:绑定的事件名
  2. function:执行的回调函数
  3. useCapture
    • false: 默认,代表冒泡时绑定
    • true: 代表捕获时绑定

e.target和e.currentTarget

在以上的例子中新增js代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="a">
<div class="b">
<div class="c">
</div>
</div>
</div>
<script>
const a =document.querySelector('.a')
const b =document.querySelector('.b')
const c =document.querySelector('.c')

a.addEventListener('click', function(e) {
console.log(`target: ${e.target.className}, currentTarget:${e.currentTarget.className}`)
})
b.addEventListener('click', function(e) {
console.log(`target: ${e.target.className}, currentTarget:${e.currentTarget.className}`)
})
c.addEventListener('click', function(e) {
console.log(`target: ${e.target.className}, currentTarget:${e.currentTarget.className}`)
})
</script>

点击c元素,控制台打印结果为:

1
2
3
target: c, currentTarget:c
target: c, currentTarget:b
target: c, currentTarget:a

由此我们可以得出结论e.target为我们点击的元素(可以理解为c在a、b的上层,所以我们点击的是c),e.currentTarget为绑定事件的元素(这里是冒泡,所以从c->a)

 事件委托

考虑一个需求:

1
2
3
4
5
6
<ul class="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>

如上所示,ul中有4个li,如果我们想在点击li后输出对应li的内容怎么办?

没错,我们可以给每个li都绑定一个事件,但你有没有想过,这里只有4个li,实际应用场景可能不止这么多,那难道我们给每个li都绑定事件吗?

利用我们之前所学的知识,我们可以进行如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
<ul class="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>

<script>
const ul = document.querySelector('.ul')
ul.addEventListener('click', function(e) {
console.log(e.target.innerHTML)
})
</script>

这就是事件委托啦,就是把子元素的事件,其原理就是利用事件冒泡e.target,把处理子元素的操作,委托在父元素的事件中处理。,


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!