jQuery事件处理(一)
1、jQuery事件绑定的用法:
$( "elem" ).on( events, [selector], [data], handler );
events:事件名称,可以是自定义事件名称
selector:选择器
data:事件触发时传递给事件处理函数
handler:事件处理函数
2、on方法源码分析
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
var origFn, type;
// 如果types是对象,则说明是传入了多个事件
if ( typeof types === "object" ) {
// 如果selector不是string,则说明用户没有传入selector
if ( typeof selector !== "string" ) {
// 把selector赋值给data
data = data || selector;
// selector置为undefined
selector = undefined;
}
// 遍历types对象中的每一个元素,并递归调用自身
for ( type in types ) {
this.on( type, selector, data, types[ type ], one );
}
return this;
}
// 如果data和fn都为null,说明用户只传了前两个参数
if ( data == null && fn == null ) {
// 把selector(第二个参数)赋值给fn
fn = selector;
// data和selector置为undefined
data = selector = undefined;
// 如果fn为null,说明用户传了三个参数
} else if ( fn == null ) {
// 如果selector的类型是string,说明用户没传data
if ( typeof selector === "string" ) {
// 把data赋值给fn
fn = data;
// 把data置为undefined
data = undefined;
} else {
// 否则的话,说明用户没传selector,而是传了data,将data赋值给fn
fn = data;
// 将selector赋值给data
data = selector;
// 将selector置为undefined
selector = undefined;
}
}
// 如果用户传入的事件处理函数是false值,则将事件处理函数赋值为jQuery内部的returnFalse函数
if ( fn === false ) {
fn = returnFalse;
// 如果用户没传回调函数,返回this,this是啥?返回this干嘛?
} else if ( !fn ) {
return this;
}
// 如果one为1,内部用,暂时没看到用途
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++ );
}
// 遍历this对象,调用jQueryevent对象的add方法处理事件
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
},
通过分析on方法的源码发现,on方法并没有处理事件相关的任何事情,只是对用户传入的参数进行调整,真正处理事件的是event对象
3、首先看看event对象的构造函数都做了什么
jQuery.Event = function( src, props ) {
// 余老板的suggest组件中也用到了这种方法
// 检测this是不是Event对象,如果不是,new一个Event对象出来,这样就避免了外部new对象
if ( !(this instanceof jQuery.Event) ) {
return new jQuery.Event( src, props );
}
// 如果有src,并且src有type属性
if ( src && src.type ) {
// 定义originalEvent属性并将src赋值给它
this.originalEvent = src;
// 定义type属性,并将src.type赋值给它
this.type = src.type;
// 定义isDefaultPrevented属性并通过判断事件被阻止冒泡为其赋值
this.isDefaultPrevented = ( src.defaultPrevented ||
src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
// 否则,将src赋值给type
} else {
this.type = src;
}
// 如果用户传入props,则扩展Event或者覆盖原有的属性
if ( props ) {
jQuery.extend( this, props );
}
// 创建一个时间戳??
this.timeStamp = src && src.timeStamp || jQuery.now();
// 给这个Event对象一个标记
this[ jQuery.expando ] = true;
};
看event对象的构造函数发现,构造函数做了一些初始化操作。在看一下event对象封装的一些方法。
4、jQuery的event对象
jQuery的event对象提供了如下方法和属性:
{
add : function(){},
remove : function(){},
trigger : function(){},
dispatch : function(){},
handlers : function(){},
fix: function(){},
simulate : function(){},
global : {},
props : {},
fixHooks : {},
keyHooks : {},
mouseHooks : {},
special : {}
}
首先看add方法:
add: function( elem, types, handler, data, selector ) {
var handleObjIn, eventHandle, tmp,
events, t, handleObj,
special, handlers, type, namespaces, origType,
elemData = data_priv.get( elem );
// 涉及到jQuery的另外一个大的方面:缓存机制。或许我应该先看缓存机制的。。。
// 不为text、comment节点绑定数据,直接返回
if ( !elemData ) {
return;
}
// 如果handler是一个有handler属性或方法的对象,则进行一些转移赋值操作
if ( handler.handler ) {
handleObjIn = handler;
handler = handleObjIn.handler;
selector = handleObjIn.selector;
}
// 检查handler是否有一个唯一的id,方便之后查找和删除
if ( !handler.guid ) {
// 如果没有就为其设定一个唯一id
handler.guid = jQuery.guid++;
}
// 如果elemData中没有events对象,则为其定义events属性并赋值为空对象
if ( !(events = elemData.events) ) {
events = elemData.events = {};
}
// 如果elemData中没有handle对象
if ( !(eventHandle = elemData.handle) ) {
// 为elemData定义一个handle方法(事件处理函数)
eventHandle = elemData.handle = function( e ) {
// 有点迷糊。。。
return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
undefined;
};
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
eventHandle.elem = elem;
}
// 处理types中传入的是通过空格分割的多个事件的情况
types = ( types || "" ).match( core_rnotwhite ) || [""];
t = types.length;
while ( t-- ) {
tmp = rtypenamespace.exec( types[t] ) || [];
type = origType = tmp[1];
namespaces = ( tmp[2] || "" ).split( "." ).sort();
if ( !type ) {
continue;
}
// 事件是否会改变当前状态,如果是则使用特殊事件,看event的special属性。。。
special = jQuery.event.special[ type ] || {};
// 根据是否有selector判断使用哪种特殊事件(看完特殊事件再过来看这个地方)
type = ( selector ? special.delegateType : special.bindType ) || type;
// 根据新的type获取新的special
special = jQuery.event.special[ type ] || {};
// 组装用于特殊事件处理的对象
handleObj = jQuery.extend({
type: type,
origType: origType,
data: data,
handler: handler,
guid: handler.guid,
selector: selector,
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
namespace: namespaces.join(".")
}, handleObjIn );
// 如果是第一次调用,初始化事件处理队列(将同一事件的处理函数放入数组中)
if ( !(handlers = events[ type ]) ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
// 如果获取特殊事件监听方法失败,则使用addEventListener添加事件(抛弃attachEvent了吗?)
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
}
}
}
// 使用special的add方法进行处理
if ( special.add ) {
// 添加事件
special.add.call( elem, handleObj );
// 设置handleObj中的handler属性的id
if ( !handleObj.handler.guid ) {
handleObj.handler.guid = handler.guid;
}
}
// ???
if ( selector ) {
handlers.splice( handlers.delegateCount++, 0, handleObj );
} else {
handlers.push( handleObj );
}
// 现在还没看到是干啥用的。
jQuery.event.global[ type ] = true;
}
// 将elem清空,等待回收,避免内存泄漏
elem = null;
},
jQuery事件处理(一)的更多相关文章
- [DOM Event Learning] Section 3 jQuery事件处理基础 on(), off()和one()方法使用
[DOM Event Learning] Section 3 jQuery事件处理基础 on(),off()和one()方法使用 jQuery提供了简单的方法来向选择器(对应页面上的元素)绑定事件 ...
- jQuery事件处理了解一下
>>> JQuery 事件处理 一.事件绑定方式 1.事件绑定的快捷方式: 缺点:绑定的事件,无法取消 $("button:eq(0)").dblclick(fu ...
- jQuery事件处理(四)
看了几天,决定整理一下jQuery事件处理的整体设计思路 1.通过add方法给选中的元素注册事件处理程序(通过缓存系统将事件储存到cache,而不是绑定到元素上) a.在存储之前,会为事件处理程序增加 ...
- Unit02: jQuery事件处理 、 jQuery动画
Unit02: jQuery事件处理 . jQuery动画 jQuery实现购物车案例 <!DOCTYPE html> <html> <head> <titl ...
- JQuery事件处理的注意事项
1.jQuery 名称冲突 jQuery 使用 $ 符号作为 jQuery 的简介方式. 某些其他 JavaScript 库中的函数(比如 Prototype)同样使用 $ 符号. jQuery 使用 ...
- 02-老马jQuery教程-jQuery事件处理
1. 绑定简单事件 在DOM中DOM0级绑定事件的方式是直接给事件属性赋值,但是这样有个缺点就是每次指定的事件处理程序会把之前的覆盖掉. jQuery简单绑定事件的方式,可以让我绑定多个事件处理程序跟 ...
- jQuery事件处理(七)
1.自定义事件(用户手动trigger的一般都是自定义事件) trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tm ...
- jQuery事件处理(六)
1.通过一步步调试的的方法观察了一下存放到cache中的事件及其处理程序的数据格式: { events : { // 根据事件类型存放添加到该元素上的所有事件,下面以click为例 click : [ ...
- jQuery事件处理(五)
对原生js不熟悉看jQuery会困难很多.后续需要更多的关注下原生js jQuery封装之后的事件触发,其中一个分支(处理普通事件)是通过:elem.addEventListener( type, e ...
随机推荐
- MySQL中information_schema是什么
转载地址:http://help.wopus.org/mysql-manage/607.html 大家在安装或使用MYSQL时,会发现除了自己安装的数据库以外,还有一个information_sche ...
- C# WinForm下,隐藏主窗体的方法
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 让小区运营再智能一点,EasyRadius正式向WayOs用户提供到期弹出式提示充值页面
其实一直没向用户提供到期弹出式页面,主要是给VIP群的用户一点优越感,随着这次EasyRadius的更新,海哥就免费向普通easyRadius用户提供这两个模板下载. 有些人会问,什么样的模板.有什么 ...
- iOS:根据系统类型加载不同的xib
1.将 xib 文件名手动更改为 xxx~iphone.xib 和 xxx~ipad.xib 2.初始化时使用 [[xxx alloc] init] 即可,系统会自动判断系统类型并加载对应的 xib ...
- spark 非常好的学习内容
http://homepage.cs.latrobe.edu.au/zhe/ZhenHeSparkRDDAPIExamples.html
- 利用neon技术对矩阵旋转进行加速
一般的矩阵旋转操作都是对矩阵中的元素逐个操作,假设矩阵大小为m*n,那么时间复杂度就是o(mn).如果使用了arm公司提供的neon加速技术,则可以并行的读取多个元素,对多个元素进行操作,虽然时间复杂 ...
- php创建文件夹
$dir = iconv("UTF-8", "GBK", "Public/bookcover"); if (!file_exists($di ...
- slab着色,可以减少cache conflict miss概率么?
以内部slab为例,管理区 + object总大小+left_over size = 1page,我们做个极端假设,cache为 direct-mapped caches. 1.没有采用slab着色: ...
- windows上完美的X-server服务器软件:MobaXterm
这个软件 太 TMD 好了 . 干净.绿色.小巧. X-server 软件.想知道如何用不,直接打开运行该软件,这样就Enough了!
- [转载]Android 生成keystore,两种方式
Refer : http://blog.csdn.net/ms03001620/article/details/8490314 一.eclipse 中生成android keystore 建立任意一个 ...