什么是事件代理(也叫事件委托)
事件代理是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。比如,我们有一个ul
元素,里面有很多li
元素,我们想要给每个li
元素添加点击事件。有两种方法可以完成这件事:
- 给每个
li
元素都添加一个点击事件,弊端是如果li
元素很多的话,就会导致代码很冗余,如果后面还有新的li
元素添加进来,还需要给新的li
元素添加点击事件,导致代码很难维护。 - 给
ul
元素添加一个点击事件,然后在事件处理程序中判断点击的是哪个li
元素,然后执行对应的操作即可,简洁高效。这种方法就是事件代理
。
事件代理的原理
事件代理的原理是利用事件冒泡,将本应由被点击元素处理了的事件委托给其父元素来处理,这样就可以在事件处理程序中判断点击的是哪个元素,然后执行对应的操作。
不支持事冒泡的事件无法使用事件代理,比如blur
、focus
、load
、unload
等事件。
示例代码
下面代码为ul
元素添加了一个点击事件,然后在事件处理程序中判断点击的是哪个li
元素,然后执行对应的操作。
1 | <ul id="list"> |
1 | const list = document.getElementById('list'); |
而下面的代码为table元素添加了点击事件,然后在事件处理程序中判断点击的是哪个td
元素,然后执行对应的操作。
1 | <table id="my-table"> |
1 | const table = document.getElementById("my-table"); |
为啥突然想到这个呢?
因为最近在做一个drag and drop的app,需要在拖拽的时候显示preview(被拖拽元素跟着鼠标走),需要一个操作就是克隆被拖拽的元素,而cloneNode这个方法是无法克隆事件的(只能克隆inline事件,无法克隆通过属性或者event listener添加的事件),而如果使用的是事件代理模式,则不存在这个问题。