1、事件代理是什么?
事件代理,通俗来讲就是把一个元素响应事件(click,keydown…)的函数委托到另一个元素。
事件流都会经过三个阶段:捕获阶段–>目标阶段----->冒泡阶段
事件委托就是在冒泡阶段完成,
事件委托是会把一个或者一组元素的事件委托到它的父层或者更外层的元素上,真正绑定事件的是外层元素,而不是目标元素。
当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。
举例:
一个宿舍的同学的快递同时到了,一种笨方法就是让他们一个个去取。
较优的方法是把这件事委托给宿舍长,让一个人出去拿好所有的快递,然后再根据收件人一一分发给同学。
在这个例子中,取快递就是一个事件,每个同学指的是需要响应事件的DOM元素,而出去统一领取快递的宿舍长就是代理的元素。
所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。
2、应用场景
如果有一个列表,列表中有大量的列表项,需要在点击列表项的时候响应一个事件。
如果给每个列表项都一一绑定一个函数,那对于内存消耗是非常大的。
这时候就可以事件委托,把点击事件绑定在父级元素ul上,然后执行事件的时候再去匹配目标元素
还有一种场景是上述列表项并不多,我们给每个列表都绑定了事件
但是如果用户能够随时动态的增加或者去除列表项的元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件。
如果用了事件委托就没有这种麻烦,因为事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配。
举例:
在下面html结构中,点击input可以动态添加元素。
使用事件委托
可以看到,使用事件委托,在动态绑定事件的情况下可以减少很多重复工作的。
3、总结
适合事件委托的事件有:click、mousedown、mouseup、keydown、keyup、keypress
从上面应用场景中可以看出使用事件委托存在两个优点:
减少整个页面所需的内存,提高整体性能。
动态绑定,减少重复工作量
使用事件委托也存在局限性:
focus、blur这些时间没有冒泡机制,所以无法进行委托绑定事件
mousemove、mouseout这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的
如果把所有事件都用事件代理,可能出现事件误判,即本不该触发的事件绑定了事件。