前置知识
事件冒泡 && 事件捕获
当我们触发一个元素事件时,如果事件从最内层元素传递到最外层元素,此过程为事件冒泡,如果从最外层元素传递到最内层元素,此过程为事件捕获
如以下代码所示:
- 若触发
事件冒泡,则事件执行顺序为c、b、a
- 若触发
事件捕获,则事件执行顺序为a、b、c
1 2 3 4 5 6
| <div class="a"> <div class="b"> <div class="c"> </div> </div> </div>
|
Javascript中addEventListener为元素绑定事件的方法,它接收三个参数
- event:绑定的事件名
- function:执行的回调函数
- 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,把处理子元素的操作,委托在父元素的事件中处理。,