js事件代理

前端面试中,事件代理也是我们经常会遇到的一个问题,下面我们来聊一下事件代理的原理。

原理

比如说我们想个一个列表中的每一项绑定一个点击事件,如果我们一个一个去给每一项绑定事件,则会导致多次操纵dom,效率也比较低,如果添加一个新的选项的话,还得再给这个选项绑定事件。

事件代理,其实就是将事件绑定在父元素上,然后通过父元素的点击事件来判断点击的是不是子元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var ul = document.getElementById('test')
ul.addEventListener('click', function (event) {
var target = event.target
if (target.tagName.toUpperCase() === 'LI') {
console.log(target.innerText)
}
})

</script>

我们通过绑定父元素的点击事件,通过获取 event.target 可以知道当前点击的元素,在 IE 6-8中不支持该属性,有一个 srcElement 等价于这里 target

currentTarget

如果我们打印出 event 可以看到里面有一个 currentTarget 属性,并且这个属性为 null,那么这个属性有什么用呢。

这里我们可以这样试一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14

<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var ul = document.getElementById('test')
ul.addEventListener('click', function (event) {
console.log(event)
console.log(event.currentTarget)
})
</script>

可以发现event.currentTarget打印出来的是 ul这个节点。看 mdn 的文档可知道,这个属性是指向当前事件被绑定的元素上

在js中console.log(obj)打印对象的时候,是对对象的一个引用,如果对象的属性后面被改变了,打印出来的对象也是会发生改变的,所以造成了前面打印 event 的时候发现他的currentTarget为null