读jQuery之十一 添加事件核心方法_jquery

这篇看看其源码,这个add定义如下(省略大部分)

复制代码 代码如下:

add: function( elem, types, handler, data ) {
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
return;
}
...
}

定义了四个参数elem、types、handler和data分别为HTMLElement、事件类型(如click)、事件响应函数、数据。此外,types 可以以空格分开传多种事件("mouseover mouseout")。handler 有时会是一个对象(实现live时)。data 最后会挂在扩充后的event对象上,即作为event的属性。而event会在handler作为第一个参数拿到,这样也就可以在handler拿到data了。
下面详细说明

复制代码 代码如下:

if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
return;
}

文本和注释节点直接返回。

复制代码 代码如下:

if ( handler === false ) {
handler = returnFalse;
} else if ( !handler ) {
// Fixes bug #7229. Fix recommended by jdalton
return;
}

参数handler为false时,将handler赋值为returnFalse,returnFalse为一个函数,如下

复制代码 代码如下:

function returnFalse() {
return false;
}

jQuery通过handler为false来阻止元素默认行为,停止事件冒泡。这个需要结合jQuery.event.handle看。

复制代码 代码如下:

var handleObjIn, handleObj;
if ( handler.handler ) {
handleObjIn = handler;
handler = handleObjIn.handler;
}
// Make sure that the function being executed has a unique ID
if ( !handler.guid ) {
handler.guid = jQuery.guid++;
}

定义变量handleObjIn,handleObj。
handler从字面上看是事件响应(回调)函数,但这里出现handler.handler,让人倍感怪异。即什么时候会将handler当一个JS对象传入呢?
多数时候传的还是Function类型的,看看源码中jQuery.event.add的调用可发现jQuery在实现live的时候会传Object类型。如下

复制代码 代码如下:

add: function( handleObj ) {
jQuery.event.add( this,
liveConvert( handleObj.origType, handleObj.selector ),
jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
},

这时会把handleObjIn赋值为所传的JS对象,真正的handler 却是handleObjIn.handler。这话有点绕,慢慢体会。

复制代码 代码如下:

// Make sure that the function being executed has a unique ID
if ( !handler.guid ) {
handler.guid = jQuery.guid++;
}

所传参数handler添加个属性guid,为一个数字,自增的从1开始。即使用jQuery添加事件,会为事件响应函数默认的添加了属性guid。这个guid再删除事件时会用到。

复制代码 代码如下:

// Init the element's event structure
var elemData = jQuery._data( elem );

先取elemData,这里使用了前面提到的jQuery._data。第一次为HTMLElement添加事件是elemData是个空对象({})。

复制代码 代码如下:

// If no elemData is found then we must be trying to bind to one of the
// banned noData elements
if ( !elemData ) {
return;
}

elemData不存在则直接返回。

复制代码 代码如下:

var events = elemData.events,
eventHandle = elemData.handle;

定义events,eventHandle。同样第一次时这两个变量都是undefined。

复制代码 代码如下:

if ( !events ) {
elemData.events = events = {};
}
if ( !eventHandle ) {
elemData.handle = eventHandle = function( e ) {
// Discard the second event of a jQuery.event.trigger() and
// when an event is called after a page has unloaded
return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
undefined;
};
}

给elemData.events和elemData.handle赋值。

复制代码 代码如下:

// Add elem as a property of the handle function
// This is to prevent a memory leak with non-native events in IE.
eventHandle.elem = elem;

暂存elem到eventHandle,删除事件注册时会将其置null,避免部分浏览器中内存泄露。

复制代码 代码如下:

// Handle multiple events separated by a space
// jQuery(...).bind("mouseover mouseout", fn);
types = types.split(" ");

将字符串以空格为切割符转成数组。这句使其可以一次添加多个事件,多个事件的handler是相同的。
后面是一个while循环

复制代码 代码如下:

while ( (type = types[ i++ ]) ) {
handleObj = handleObjIn ?
jQuery.extend({}, handleObjIn) :
{ handler: handler, data: data };
...
}

循环数组,里面依次处理如下
, 取得handleObj
, 处理事件命名空间,以点号(.)来区别。如果type有点号,则具有命名空间,否则没有
, 给handlerObj添加type,guid属性。这些后续删除事件时用到
, 取到handlers,special。多数情况下使用addEventListener/attachEvent来添加事件。从变量special可看出对于特殊的事件如ready,beforeunload及live事件是特殊处理的。 ready 调用的是jQuery.bindReady,而jQuery.bindReady内部调用的仍然是 addEventListener/attachEvent。beforeunload则是使用window.onbeforeunload来添加。live是实现事件代理的,他的处理也是特殊的。
, 最后吧handleObj添加到数组handles中。
jQuery.event.add 的最后一句,解决IE中内存泄露。

复制代码 代码如下:

// Nullify elem to prevent memory leaks in IE
elem = null;

jQuery事件管理的数据结构,我做了个图。如下

时间: 2024-09-16 21:23:40

读jQuery之十一 添加事件核心方法_jquery的相关文章

jQuery为动态生成的select元素添加事件的方法_jquery

项目中需要在点击按钮时动态生成select元素,为防止每次点击按钮时从服务器端获取数据(因为数据都是相同的),可以这样写代码 1.首先定义全局js变量 var strVoucherGroupSelect =""; 2.在js中写好获取服务端数据的代码 function genVoucherGroupSelect(rowID){ return $(strVoucherGroupSelect).attr("id", "sl_" + rowID).pa

jQuery简单获取键盘事件的方法_jquery

本文实例讲述了jQuery简单获取键盘事件的方法.分享给大家供大家参考,具体如下: 一.我们什么时候要用到获取键盘事件 做web的时候,为了更人性的设计,我们有的时候会用到键盘事件.例如:输入框下拉提示框,通过键盘的上下键盘来选择自己想要的内容,google的输入框的下拉提示.当我们浏览相册的时候,我们可以能过键盘的左右键,来查看相片.当我们浏览长篇小说,用鼠标滚动很容易不知道看到哪一个行了,可以通键盘上下键来进行翻页,这些小细节也是非常重要的.做网站很大程度在于细节的处理. 二.jquery的

读jQuery之十二 删除事件核心方法_jquery

.remove 所作的事情与上一篇提到的.add 刚好相反.且与.add中的处理代码一一对应,即  .add 中有多少种添加事件的方式.remove就有对应的删除方式. .remove 定义了四个参数 elem, types, handler, pos .从字面上看四个参数的意义很明了 elem 为HTMLElement types 为String类型,事件名称如'click'或'mouseover mouseout'   handler 为Function类型,事件回调函数 pos 为Numb

jquery中获得$.ajax()事件返回的值并添加事件的方法_jquery

如果想获得$.ajax()中返回的值,直接用在success:funciton(){return xx} 是不可以的,要想获得xx的值,要在script中,使用全局变量.利用全局变量引出xx的值. jquery 取得$.ajax事件中的返回值,并添加事件 复制代码 代码如下: <html> <head> <title>测试JQUERY提交动态文本</title> <script language="javascript" src=&

读jQuery之十三 添加事件和删除事件的核心方法_jquery

jQuery的事件模块严重依赖于其数据储存(jQuery.data),你会发现我的代码中的dataManager对象对应它. 这里只提供bind和unbind方法.暂不包含 1, 事件命名空间(event namespace) 2, 事件代理(event delegation) 3, 特殊事件如dom ready 接口如下: 复制代码 代码如下: E.bind(el, 'click', fn); E.bind(el, 'click', fn, data); E.unbind(el, 'click

jQuery给元素添加样式的方法详解_jquery

本文实例讲述了jQuery给元素添加样式的方法.分享给大家供大家参考,具体如下: 1.获取和设置样式 $("#tow").attr("class")//获取ID为tow的class属性 $("#two").attr("class","divClass")//设置Id为two的class属性. 2.追加样式 复制代码 代码如下: $("#two").addClass("divCl

JS脚本实现动态给标签控件添加事件的方法_javascript技巧

本文实例讲述了JS脚本实现动态给标签控件添加事件的方法.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> &l

js实现为a标签添加事件的方法(使用闭包循环)_javascript技巧

本文实例讲述了js实现为a标签添加事件的方法.分享给大家供大家参考,具体如下: 以示例说明: 实现效果:循环为带有ml-praise样式类的a标签添加事件,并且在点击a标签后,相应的数量增加1. Html结构如下所示: <ul> <li><a href="javascript:;" class="ml-praise">数量:<span class="ding-num">100</span>

VC实现给窗体的一个按钮添加事件的方法_C 语言

本文实例讲述了VC实现给窗体的一个按钮添加事件的方法.分享给大家供大家参考.具体实现方法如下: 1. 在MainFrm.h中 复制代码 代码如下: // Generated message map functions 添加: 复制代码 代码如下: afx_msg void OnSelectRed(); //声明事件名称 2. MainFrm.cpp中 复制代码 代码如下: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)下面 添加: 复制代码 代码如下: ON_C