注明:以下jquery经验版本均自jquery1.7+版本。
一. jQuery事件总结
1.1 ready事件和window.onload事件
$(document).ready(); 和 window.onload 的方法有相似功能,但是又有区别。
加载时机
$(document).ready(); 表示DOM完全解析就绪就可以被调用。
window.onload 要等到包括图片,js等资源加载完全后才会被调用。 而其实如图片并不是js执行的必须条件。
推荐使用ready方法。
如果是图像处理相关,要获取图片相关信息的,也可以用onload事件。
多次使用
ready事件多次重复绑定,这些绑定的处理方法会被依次执行。
window.onload方法只能绑定一个处理方法,如果绑定多个,只有最后一个会被执行。
1.2 ready事件的等同写法
//第一种,清晰写法
$(document).ready(function(){
//do some thing
});
//第二种,即使不显式传入document,默认会绑定document
$().ready(function(){
//do some thing
});
//第三种,最简写, 等同以上两种写法
$(function(){
//do some thing
});
1.3 ready 事件的执行时机
1. ready事件除了在第一次页面DOM加载完成后会执行;在页面已经运行一段时间后,再次绑定ready事件,同样会被执行。
2. 在页面加载完成后的动态更新,可以用匿名方法方式。如:
void function(j){
}(jQuery);
以上方法不会追加到document的ready事件队列中,而是执行完毕后,可以释放内存。
二. jQuery事件绑定(bind() delegate() on()的区别)
2.1 事件绑定之间的关系
代码2-1是来自jquery源码中的 bind 及 delegate 和on 扩展的源代码,从代码中我们可以看出,jquery中事件绑定(bind,delegate,one)的源头都是 on方法。
jQuery.fn.extend({
hover: function( fnOver, fnOut ) {
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
},
bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},
unbind: function( types, fn ) {
return this.off( types, null, fn );
},
delegate: function( selector, types, data, fn ) {
return this.on( types, selector, data, fn );
},
undelegate: function( selector, types, fn ) {
// ( namespace ) or ( selector, types [, fn] )
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
}
});
one: function( types, selector, data, fn ) {
return this.on( types, selector, data, fn, 1 );
}
代码2-1
我们来研究一下 on方法提供了哪些事件绑定的特性。
on(events,[selector],[data],fn) :附加一个事件处理函数的一个或多个事件到选定的元素,无论选择出的目标元素是当前存在还是将来创建。
参数
events,[selector],[data],fnV1.7
events:一个或多个用空格分隔的事件类型和可选的命名空间,如"click"或"keydown.myPlugin" 。
selector:一个选择器字符串用于过滤器的触发事件的选择器元素的后代。如果选择的< null或省略,当它到达选定的元素,事件总是触发。
data:当一个事件被触发时要传递event.data给事件处理函数。
fn:该事件被触发时执行的函数。 false 值也可以做一个函数的简写,返回false。
其它几个通过on事件扩展绑定事件的使用说明:
方法名
参数
说明
bind方法
type,[data],function(eventObject)
给选定的元素绑定事件
delegate方法
selector,[type],fn
该方法可以基于某些特定元素(通过选择器得到),附加一个或多个事件到特定元素内部选择器指定的元素上,无论选择出的目标元素是当前存在还是将来创建。
one方法
type,[data],function(eventObject)
给选定的元素绑定事件, 只执行一次
事件绑定示例:
$(function(){
// 给parentContainer绑定click事件
$("#parentContainer").bind('click',function(){
//执行操作
});
// 给parentContainer的子元素(.Jupdate) 绑定click事件,(后期创建的也可执行)
$("#parentContainer").delegate('.JUpdate','click',function(){
//执行更新操作
});
});
在我们常用的往dom节点上绑定事件的时候,除了以下这种绑定方式,还有其他几种绑定事件的方式
j("#btn").click(function(){
});
2.2 动态绑定是如何实现的?事件冒泡
为什么on方法可以对一个尚未创建的对象进行事件绑定?这就需要讨论javascript的事件传递机制。
DOM树
首先,可视化一个HMTL文档的DOM树是很有帮助的。一个简单的HTML页面看起来就像是这个样子:
事件冒泡(又称事件传播)
当我们点击一个链接时,其触发了链接元素的单击事件,该事件则引发任何我们已绑定到该元素的单击事件上的函数的执行。
$('a').bind('click', function() { alert("That tickles!") });
因此一个单击操作会触发alert函数的执行。
click事件接着会向树的根方向传播,广播到父元素,然后接着是每个祖先元素,只要是它的某个后代元素上的单击事件被触发,事件就会传给它。
在操纵DOM的语境中,document是根节点。
所以当你点击 a 子节点的时候,a的事件会逐级上传,如果每一级都绑定了事件,则每级的事件都会执行;当你在p父节点通过delegate绑定事件后,父节点会判断事件触发的节点是否和当前选择器符合,如果符合则可以。
所以,通过 on或者delegate绑定的事件,实际上是绑定到父节点上的,当子节点发生事件后,父节点可以通过动态判断是否该子节点符合当前的选择器来决定是否触发事件方法。
2.3 事件阻止
在上面的2.2中,我们看到了事件的冒泡传递方式。但是有时候,我们希望当前按钮处理绑定在它上面的事件后,不再继续往上传递
$("#btn").click(function(event){
event.stopPropagation(); //调用后,事件不再往上冒泡传递
event.preventDefault(); //调用后,事件默认的行为被阻止,如 a标签的跳转
});
2.4 DOM节点被销毁后,jquery绑定的事件去哪儿了?
on 方法的源码最终的事件绑定是调用的 jQuery.event.add 方法
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
而jQuery.event.add 方法最终的事件绑定是这样的:
// Init the event handler queue if we're the first
if ( !(handlers = events[ type ]) ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
// Only use addEventListener/attachEvent if the special events handler returns false
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
// Bind the global event handler to the element
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
} else if ( elem.attachEvent ) {
elem.attachEvent( "on" + type, eventHandle );
}
}
}
最终事件绑定到了具体的DOM元素节点上,调用的原生javascript的事件绑定:
addEventListener (Mozilla,chrome适用)
attachEvent (IE适用)
以上两个方法源自 《DOM Level 2模型》,该功能可以实现在一个DOM节点上,绑定多个同样的事件处理,这些绑定的事件会被依次执行。
可以推断如下:处理事件是被绑定在dom节点上,随DOM节点的回收,绑定的事件亦可随之而被回收。
以此推断,对于其它地方有没有对事件对象造成引用和缓存没有进行进一步的细究,本结论为 待确认观点。
三. 引用资源
1. http://developer.51cto.com/art/201103/249694.htm (jQuery的.bind()、.live()和.delegate()之间区别)
2. http://www.jb51.net/article/18220.htm (Javascript 的addEventListener()及attachEvent()区别分析)
3. http://jquery.cuishifeng.cn/index.html (jQuery API速查 1.11.2)
4.http://code.jquery.com/jquery-1.11.2.js ( jQuery源码下载)