事件代理
一、事件代理是什么
事件代理(事件委托),是把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素
事件流的三个阶段:捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就在冒泡阶段完成
当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数
举例理解
宿舍买饭,一个个去买方法就比较笨,可以让宿舍长买完宿舍所有人的饭
这个例子中,每个宿舍成员就是需要响应事件的DOM元素,代买饭的宿舍长就是代理元素
二、应用场景
实例一:动态响应事件
现有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
传统给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的
//获取目标元素
const lis = document.querySelectorAll('li')
//循环绑定事件
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', function (e) {
console.log(e.target.innerHTML)
})
}
这时候就可以事件委托,把点击事件绑定在父级元素ul上面,然后执行事件的时候再去匹配目标元素
// 给父层元素绑定事件
document.querySelector('ul').addEventListener('click', function (e) {
if (e.target.tagName.toLowerCase() === 'li') {
console.log(e.target.innerHTML) //输出为li的内容
}
})
实例二动态添加元素
<button>添加元素</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
const btn = document.querySelector('button')
const ul = document.querySelector('ul')
let num = 3
//业务:点击按钮,向ul中插入一个li,并页面展示
btn.addEventListener('click', function () {
const li = document.createElement('li')
li.innerHTML = ++num
ul.appendChild(li)
})
可以看到,使用事件委托,在动态绑定事件的情况下是可以减少很多重复工作的
三、总结
适合事件委托的事件有:click,mousedown,mouseup,keydown,keyup
事件委托存在两大优点:
-
减少整个页面所需的内存,提升整体性能
-
动态绑定,减少重复工作
但是使用事件委托也是存在局限性:
-
focus、blur这些事件没有事件冒泡机制,所以无法进行委托绑定事件 -
mousemove、mouseout这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的