标签:
什么是事件代理?首先得知道什么是事件,并且弄清楚事件流,才能真正明白事件代理原理。
javascript与HTML之间交互就是通过事件实现的,事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。如onload、onclick、onmouseup、onmousedown... 。
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
因为历史的原因,IE最开始实现实现事件流的方式:冒泡事件(event bubbling),Netscape提出了另外一种事件流方式:事件捕获(event capturing),不同的浏览器实现上有一些差别,用起来就有些繁琐。幸好现代浏览器都实现了W3C制定的"DOM2级事件","DOM2级事件"把事件流分为三个阶段,捕获阶段、目标阶段、冒泡阶段。
网上借图:
前面做了这么多基础铺垫,那么现在理解事件代理就是很简单的事了。事件代理就是在祖先级DOM元素绑定一个事件,当触发子孙级DOM元素的事件时,利用事件流的原理来触发绑定在祖先级DOM的事件。听起来有点绕口,下面做一个简单的代码实现:
<!--省略html主体部分--> <ul id="menu"> <li><p><a>如果我被钗神翻牌,我就有一个成为大神的机会!</a></p></li> <li><p><a>如果我被钗神翻牌,我就有一个成为大神的机会!</a></p></li> <li><p><a>如果我被钗神翻牌,我就有一个成为大神的机会!</a></p></li> <!--中间省略1000000行--> <li><p><a>如果我被钗神翻牌,我就有一个成为大神的机会!</a></p></li> </ul>
// 获取祖先节点(这儿就获取ul),并为它添加一个click事件 document.getElementById("menu").addEventListener("click", function(e) { // 检查事件源e.targe是否为A if(e.target && e.target.nodeName.toUpperCase == "A") { console.log("钗神翻我牌,今晚就跟你走...."); } });
浏览器的能力还是有限的,为了安全起见,系统分配给浏览器的内存也是有限的。特别是某些老版本的浏览器,如果在DOM上添加的事件过多,会导致网页的性能下降甚至崩溃。看我上面的ul下面的a节点就有1000004,如果真的为所有的a标签加一个事件,这个代价是很大的。用了事件代理,我们节约了1000003个事件,简直太强大了。
一般浏览器触发事件都是在冒泡阶段,如果你想在捕获阶段触发事件你可以设置addEventListener第三个参数为true,addEventListener("click", function(e){}, true)。
总结:基础很重要,明白基础,原理就是那么简单!
标签:
原文地址:http://www.cnblogs.com/webhelper/p/5616477.html