JS事件委托
DOM的事件流程
DOM的事件流程分为三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
- 首先发生的是事件捕获,为截获事件提供了机会。
- 然后是实际的目标接收到事件。
- 然后冒泡阶段发生,事件又传播回文档。
第一阶段:事件捕获。
所谓的事件捕获就是从最大范围(document)开始,一级一级往下找,知道找到最精确的事件源(触发事件的节点,如图div节点)为止的过程。虽然大多数浏览器都支持事件捕获,但很少有人使用。
第二阶段:事件触发。
找到了事件源,接下来就应当执行绑定的相应的事件(如果有的话)。
第三阶段:事件冒泡。
事件源执行完事件处理后。这个类型的事件会向祖先节点传递,直到document(包括document)(当然是在事件冒泡没有被阻止的前提下,后续的分析都是基于这个前提下)。也就是说事件源的每一个祖先节点都会触发同类事件。
想象一下,把事件源a触发click事件的处理委托给其祖先节点b。当a节点触发click,事件冒泡到b的时候,b节点也触发click事件,然后b一看事件列表中有一个委托事件,这个委托事件保存了委托节点的选择器,这个选择器所匹配节点就是事件源a,那么b马上执行这个委托事件。
什么是事件委托?
事件委托——利用事件冒泡机制,给祖先元素绑定事件,用来监听子元素的事件,将子元素的事件要做的事写到祖先元素的事件里,也就是将子元素的事件处理程序写到祖先元素的事件处理程序中。
事件委托的好处:
(1)事件委托技术可以避免对每个字元素添加事件监听器,减少操作DOM节点的次数,从而减少浏览器的重绘和重排,提高代码的性能。
设想一下,假如一个div元素的子元素中有成百上千个a标签,然后,我们要监听a标签的点击事件,如果在每个a标签上绑定元素,那么量多么大的工作,而且如果是动态添加的元素,我们还无法做到正确的监听,但是有了时间委托技术,我们完全可以在其祖先元素div上监听点击事件,然后判断事件触发的源头,进而去执行相应的事件处理程序,即可满足需求。如此,减少操作DOM节点的次数,从而减少浏览器的重绘和重排,提高了代码的性能。
(2)使用事件委托,只有父元素与DOM存在交互,其他的操作都是在JS虚拟内存中完成的,这样就大大提高了性能。
什么时候用事件委托?
一般情况下,当子元素有很多(或者说有大量子元素来自于于动态增删的时候),并且需要对子元素的事件进行监听的时候,这时候,我们推荐使用事件委托。
事件委托的实现
直接看代码吧:
1 | <div id="big"> |
1 | <style> |
1 | <script> |
很明显的可以看到,只有big绑定的click事件的事件处理程序执行了。
可以很明显的看到我们想要的当small元素被点击时,samll2函数被触发,而此时click事件绑定在small元素的祖先元素big上面,由此就实现了事件委托。
同理,可以实现,点击middle元素,利用事件委托将click事件绑定在其父元素big元素上,进而当middle被点击时,触发middle2函数。
由此,我们就简单的模拟实现了事件委托,可以很明显的发现,实现事件委托的主要手段是利用事件冒泡机制加上事件对象的target属性判断事件触发的源头,进而实现事件委托。需要提醒大家的是,IE浏览器的事件对象并不支持target属性,在IE中对应的是srcElement,这一点请大家注意。