js事件捕获,事件冒泡,事件委托以及DOM事件流

一:DOM事件流

事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段:

事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body→div

②处于目标阶段2:实际的目标到事件

事件冒泡阶段:由最具体的元素接收到事件,然后向上传播到较为不具体的节点。事件流模型:div →body→ html→ document

二:事件委托

事件委托顾名思义:将事件委托给另外的元素。其实就是利用DOM的事件冒泡原理,将事件绑定到目标元素的父节点。

如果要为大量的元素节点绑定事件,完美可以用事件委托完美解决,直接将事件绑定在这些元素的父节点上,只需要绑定一次,就可以在所有子节点触发事件。

三:常见的事件绑定:

(1)bind()

缺点:只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件,比如内容很多的时候,网页中很多内容需要点击“下一页”的时候才会被加载,则这时新加载出的元素bind则没有给他们绑定事件。

bind()不能使用的情况:

①为DOM中的很多元素绑定相同事件;

②为DOM中尚不存在的元素绑定事件;

 

解决方法:使用live()方法

(2)live()

方法会把click事件绑定到$(document)对象,而且只需要给$(document)绑定一次(不是50次,更不是5000次),然后就能够处理后续动态加载的节点的事件。在接收到任何事件时,$(document)对象都会检查事件类型和事件目标,如果是click事件且事件目标是td,那么就执行委托给它的处理程序。

缺点:

 

①$()函数会找到当前页面中的所有目标元素并创建jQuery对象,但在确认事件目标时却不用这个集合,而是使用选择符表达式与event.target或其祖先元素进行比较,因而生成这个jQuery对象会造成不必要的开销;

②默认把事件绑定到$(document)元素,如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失;

③只能放在直接选择的元素后面,不能在连缀的DOM遍历方法后面使用,即$("#info_table td").live...可以,但$("#info_table").find("td").live...不行;

④收集目标元素并创建jQuery对象,但实际操作的却是$(document)对象,令人费解。

解决方法:

①为了避免事件冒泡造成的性能损失,jQuery从1.4开始支持在使用.live()方法时配合使用一个上下文参数:

 

$("td",$("#info_table")[0]).live("click",function() {/*显示更多信息*/});

 

这样,“受托方”就从默认的$(document)变成了$("#info_table")[0],节省了冒泡的旅程。不过,与.live()共同使用的上下文参数必须是一个单独的DOM元素,所以这里指定上下文对象时使用的是$("#info_table")[0],即使用数组的索引操作符来取得的一个DOM元素。

②使用闭包:

为了避免生成不必要的jQuery对象,可以使用一种叫做“早委托”的hack,即在$(document).ready()方法外部调用.live():

(function($){
    $("#info_table td").live("click",function(){/*显示更多信息*/});
})(jQuery);

在此,(function($){...})(jQuery)是一个“立即执行的匿名函数”,构成了一个闭包,可以防止命名冲突。在匿名函数内部,$参数引用jQuery对象。这个匿名函数不会等到DOM就绪就会执行。(注意,使用这个hack时,脚本必须是在页面的head元素中链接和(或)执行的。之所以选择这个时机,因为这时候刚好document元素可用,而整个DOM还远未生成;如果把脚本放在结束的body标签前面,就没有意义了,因为那时候DOM已经完全可用了。)

 

③使用delegate()方法

(3)delegate():

 

delegate()直接将目标元素选择符("td")、事件("click")及处理程序与“受拖方”$("#info_table")绑定,不额外收集元素、事件传播路径缩短、语义明确;

delegate()支持在连缀的DOM遍历方法后面调用,即支持$("table").find("#info").delegate...,支持精确控制;

关于绑定语句的进化流程:

bind()阶段:

$("info_table td").bind("click", function();

live()阶段:

①:$("#info_table td").live("click",function()

②:$("td",$("#info_table")[0]).live("click",function()

delegate()阶段

$("#info_table").delegate("td","click",function)

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。