1).bind(“事件名”,fn)直接绑定在相应的DOM元素上,可以解决跨域问题,但对于动态生成的新元素无法自动获取事件处理函数。
解除绑定:.unbind()
$("div").bind("click",function(){
alert("bind 绑定")
})
2).delegate(selector,”事件名”,fn)绑定到父元素方,始终只监听一个,是通过冒泡的方式来绑定到指定元素上,对后来动态生成的新元素也可以绑定相应的事件。
解除绑定:.undelegate()
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</div>
$("div").delegate("p","click",function(){
alert($(this).text());
})
3).on()统一个bind和delegate的用法
解除绑定:.off()
代替bind->.on(“事件名”,fn)
代替delegate->.on(selector,”事件名”,fn)
4).one(“事件”,fn)只触发一次,触发后自动解绑
5)源码分析:他们最终都是调用on方法来完成最终的事件绑定
jq的事件注册
1》和事件同名的函数:
首先是一串包含了所有DOM元素事件的字符串,通过空格将字符串分隔成数组,如果传递的参数长度大于0,则调用jQuery对象的on方法注册事件,如果参数长度为0,则直接调用tigger方法触发事件
//循环遍历所有的dom元素事件名数组
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
//把dom元素所有事件通过fn[事件名]的方式添加到jquery对象
// Handle event binding
jQuery.fn[ name ] = function( data, fn ) {
//如果参数长度大于0,则调用on方法委托函数到name事件;如果参数长为0,则触发事件执行
return arguments.length > 0 ?
this.on( name, null, data, fn ) :
this.trigger( name );
};
});
2》绑定和委托函数:bind/unbind,delegate/undelegate,通过jQuery.fn.extend()附加到jQuery对象上
jQuery.fn.extend({
//事件绑定
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 ) {
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
}
});
3》底层注册函数on,首先,判断events是否为对象,若是对象则遍历events对象,针对每一个属性绑定on()方法,最终是通过jQuery.event.add方法进行事件绑定
jQuery.fn.extend( {
on: function( types, selector, data, fn ) {
return on( this, types, selector, data, fn );
},
//.....
//on方法对传入的参数做了一些转换
function on( elem, types, selector, data, fn, one ) {
var origFn, type;
// Types can be a map of types/handlers
if ( typeof types === "object" ) {
// ( types-Object, selector, data )
if ( typeof selector !== "string" ) {
// ( types-Object, data )
data = data || selector;
selector = undefined;
}
for ( type in types ) {
on( elem, type, selector, data, types[ type ], one );
}
return elem;
}
if ( data == null && fn == null ) {
// ( types, fn )
fn = selector;
data = selector = undefined;
} else if ( fn == null ) {
if ( typeof selector === "string" ) {
// ( types, selector, fn )
fn = data;
data = undefined;
} else {
// ( types, data, fn )
fn = data;
data = selector;
selector = undefined;
}
}
if ( fn === false ) {
fn = returnFalse;
} else if ( !fn ) {
return elem;
}
if ( one === 1 ) {
origFn = fn;
fn = function( event ) {
// Can use an empty set, since event contains the info
jQuery().off( event );
return origFn.apply( this, arguments );
};
// Use same guid so caller can remove using origFn
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
}
//最终的结果由jQuery.event.add方法实现
return elem.each( function() {
jQuery.event.add( this, types, fn, data, selector );
} );
}