`
qingfengjushi1
  • 浏览: 141091 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jquery源码分析之jQuery事件绑定

阅读更多
当使用类似以下代码时,
$(function(){ 
			$("#hr_three").click(function(event){ 
				alert('阻止时间冒泡');
				event.stopPropagation(); 
			}); 
		});
<form id="form1"> 
<div id="divOne" onclick="alert('我是最外层');"> 
<div id="divTwo" onclick="alert('我是中间层!')"> 
<a id="hr_three" onclick="alert('我是最里层!')">点击我</a> 
</div>
</div> 
</form> 

jquery会将$("#hr_three")元素与click事件进行绑定,首先jquery会进行事件注册,如下代码:
// 对以下所有事件进行绑定
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 ) {
	// Handle event binding
    // 将事件属性添加到jQuery对象
	jQuery.fn[ name ] = function( data, fn ) {
        // 根据调用参数数量进行不同调用,本例中调用this.on方法,也就是jQuery对象的on方法
		return arguments.length > 0 ?
			this.on( name, null, data, fn ) :
			this.trigger( name );
	};
} );
// 对jQuery.fn进行方法功能增强
jQuery.fn.extend( {
	on: function( types, selector, data, fn ) {
        // 调用全局on方法
		return on( this, types, selector, data, fn );
	}
...
}

function on( elem, types, selector, data, fn, one ) {
   ...
   // elem参数指向jQuery对象,调用jQuery对象each方法
   return elem.each( function() {
		jQuery.event.add( this, types, fn, data, selector );
	} );
}

jQuery.fn = jQuery.prototype = {
  ...
  each: function( callback ) {
        // each方法是由elem实例调用,因此this指向elem, 这里最终调用jQuery扩展的each方法,如下段代码
		return jQuery.each( this, callback );
	},
  ...
}

jQuery.extend( {
  ...
  each: function( obj, callback ) {
		var length, i = 0;
        // 判断是否是类数组,有length属性并且带有length - 1属性则为类数组,在init方法增强this对象时,已将        //this对象设置了这两个属性,因此增强后的this对象为类数组
		if ( isArrayLike( obj ) ) {
            
/**
                obj为jQuery对象,此对象是init方法返回的this,this为针对不同元素增强后的jQuery对象,下面代码是在init方法中对jQuery对象进行了属性增强,增加了长度属性以及0属性,
                if ( elem && elem.parentNode ) {

						// Inject the element directly into the jQuery object
						this.length = 1;
						this[ 0 ] = elem;
					}

					this.context = document;
					this.selector = selector;
					return this;
            */
			length = obj.length;
			for ( ; i < length; i++ ) {
                // 方法回调,更改回调方法上下文环境为obj[i],实际上obj[i]就是init方法的this对象的0属性,                // this[ 0 ] = elem; elem对象就是html的dom元素                
                // elem = document.getElementById( match[ 2 ] ); 因此回调方法的上下文环境就为dom元素,                // 本例中就是a元素,即document.getElementById("hr_three")
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					break;
				}
			}
		} else {
            
			for ( i in obj ) {
				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
					break;
				}
			}
		}
		return obj;
	},
  ...
});

最终调用回调方法
// this为dom元素,types为click, fn为触发方法
jQuery.event.add( this, types, fn, data, selector );

在jQuery.event.add 方法中定义事件处理方法
if ( !( eventHandle = elemData.handle ) ) {
			eventHandle = elemData.handle = 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" && jQuery.event.triggered !== e.type ?
					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
			};
		}
 ...
 // 生成处理对象
 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 );
 // 将处理对象存入到handlers数组
 if ( selector ) {
				handlers.splice( handlers.delegateCount++, 0, handleObj );
			} else {
				handlers.push( handleObj );
			}
...

对elem增加click事件监听,elem为dom元素(本例中为id是hr_three的a元素)
if ( elem.addEventListener ) {
   // eventHandle是本方法中定义的事件处理方法,见上段代码
   elem.addEventListener( type, eventHandle );
}

至此,a元素已经绑定了click事件,当a元素产生点击事件时,会触发eventHandle指向的方法。
// eventHandle指向的方法参数e为pointerEvent对象
eventHandle = elemData.handle = 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" && jQuery.event.triggered !== e.type ?
                    // elem为a元素,arguments为调用参数数组,元素0为参数e
                    // elem为jQuery.event.dispatch方法的上下文环境,arguments[0]为方法的唯一参数
					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
			};

可以通过以下代码模拟元素增加监听效果,监听方法参数e就是pointerEvent对象:
var elem = document.getElementById("hr_three");
			elem.addEventListener( "click", function(e) {
                alert('阻止事件冒泡');
                e.stopPropagation();
				console.log(e);
			} );

继续jQuery.event.dispatch方法
jQuery.event = {
...
// event参数为pointerEvent对象
dispatch: function( event ) {
    // 将pointerEvent对象转换为jQuery.Event对象
    // Make a writable jQuery.Event from the native event object    
    event = jQuery.event.fix( event );
    // 取得处理对象数组
    handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
    args[ 0 ] = event;
    // 将处理对象数组放入处理队列属性中
    handlerQueue = jQuery.event.handlers.call( this, event, handlers );
    while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
        ...
        while ( ( handleObj = matched.handlers[ j++ ] ) &&
				!event.isImmediatePropagationStopped() ) {
            ...
            /**
              调用处理方法,方法上下文为a元素,参数为jQuery.Event对象,处理方法event参数实际为args[0]指向的jQuery.Event对象,stopPropagation()方法为jQuery.Event实例方法,其中会将本实例的isPropagationStopped属性设置为true,因此再次外部while循环时,event.isPropagationStopped()即为true了。
              function(event){ 
				alert('阻止时间冒泡');
				event.stopPropagation(); 
			  }
            */
            ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
						handleObj.handler ).apply( matched.elem, args );
            
            ...
        }
        ...
    }
    
},
...
}


到此,一个完整的jQuery事件绑定及触发调用的整个过程就完成了。
分享到:
评论

相关推荐

    Jquery源码分析 源码

    《jQuery源码分析》 jQuery,作为一款广泛使用的JavaScript库,极大地简化了DOM操作、事件处理、动画制作以及Ajax交互。深入理解其源码对于提升JavaScript编程技能和优化前端性能至关重要。本文将从核心概念、设计...

    jQuery源码分析系列.pdf

    ### jQuery源码分析系列知识点概览 #### 一、总体架构与核心概念 - **前言开光**:介绍分析jQuery源码的目的和价值,强调通过深入研究源码,可以学习到先进的设计理念和实践技巧。 - **总体架构**:解析jQuery的...

    JQuery源码详细中文注释_Jquery源码分析_

    总结,jQuery源码分析涉及的内容广泛,包括选择器引擎、事件处理、DOM操作、动画效果、Ajax通信以及插件开发等多个方面。深入理解jQuery源码,有助于我们更好地利用它来构建高效、易维护的Web应用。通过阅读中文注释...

    jquery api, jquery ui api, jquery源码分析

    深入理解jQuery源码有助于开发者更好地利用其API并优化性能。主要关注点包括: 1. **选择器引擎(Sizzle)**:jQuery 使用Sizzle作为其选择器引擎,它是如何快速高效地解析CSS选择器并找到匹配元素的。 2. **链式...

    jquery 源码分析

    ### jQuery源码分析 #### 一、概述 jQuery作为一个卓越的JavaScript库,以其简洁高效的特性在前端开发领域占据了一席之地。与Prototype、YUI、Mootools等其他JavaScript库相比,jQuery更加注重实用性,去除了一些...

    jQuery源码分析(1.7)

    ### jQuery源码分析关键知识点详解 #### 一、前言 在深入了解jQuery源码之前,有必要先简要介绍一下jQuery的基本情况及其对JavaScript编程领域的重要意义。jQuery作为一个轻量级、功能丰富的JavaScript库,在Web...

    jQuery源码分析系列

    jQuery源码分析系列涉及了对jQuery库内部实现的详细解读,jQuery作为前端开发中最常用的JavaScript库之一,它简化了DOM操作、事件处理、动画效果和AJAX交互等操作。通过深入分析jQuery的源码,开发者可以学习到先进...

    jQuery源码详细分析中文注释

    这份中文注释的源码分析旨在帮助开发者逐步揭开jQuery的神秘面纱,提升JavaScript编程技能。 首先,jQuery的核心在于选择器引擎Sizzle。Sizzle是一个高效的选择器解析器,能够处理CSS1至CSS3的选择器,包括ID、类、...

    JQuery源码的奥秘逐行分析视频教程

    ### JQuery源码的奥秘逐行分析视频教程 #### JQuery简介 JQuery 是一款轻量级的 JavaScript 库,它极大地简化了 HTML 文档遍历、事件处理、动画以及 Ajax 交互等操作。JQuery 提供了一个简洁且强大的 API 接口,...

    jQuery源码分析之init的详细介绍

    接着,源码分析揭示了 init 函数的实现逻辑。函数首先检查是否有 selector 参数传入,如果没有,那么就返回 this,即一个空的 jQuery 对象。如果 selector 是字符串,则根据字符串的类型和内容,进行不同处理。对于 ...

    jquery源码框架解读

    7. **源码结构分析**:jQuery源码采用模块化设计,分为核心、选择器、遍历、DOM操作等多个部分。理解其模块划分和依赖关系,有助于我们更好地理解代码结构和逻辑。 8. **学习资源**:除了这份源码解读,还有其他...

    Head First jQuery源码

    源码分析有助于理解网络请求的流程。 7. **插件开发**:jQuery的插件机制允许开发者扩展其功能。通过源码,我们可以学习如何构建自己的jQuery插件,以及如何利用`$.fn.extend()`方法。 在学习《Head First jQuery...

    Jquery1.2.6源码分析教程

    **jQuery 1.2.6 源码分析教程** jQuery 是一个广泛使用的 JavaScript 库,因其简洁的语法和强大的功能而备受开发者喜爱。在 jQuery 1.2.6 版本中,虽然它已经相对老旧,但其背后的实现原理和优化策略仍然值得深入...

    jQuery 源码+实例+注释

    **jQuery 源码分析与实例详解** jQuery 是一个广泛使用的 JavaScript 库,它极大地简化了 JavaScript 的 DOM 操作、事件处理、动画制作以及 AJAX 交互。本教程旨在通过源码解析、实例演示和详细注释,帮助新手快速...

    jQuery 源码分析最新1.2.6

    【jQuery 源码分析最新1.2.6】 ...通过深入分析jQuery的源码,我们可以更好地理解其背后的实现原理,提升我们的JavaScript编程技巧。实际应用中,结合源码分析,可以更好地定制和优化jQuery的功能,以满足项目需求。

    jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理

    在jQuery 1.9.1中,事件系统是其核心功能之一,允许开发者方便地绑定、触发和管理事件。在本篇文章中,我们将深入探讨事件系统中的主动触发事件和模拟冒泡处理。首先,让我们来看一下`stopPropagation`函数。 `...

    Jquery1.2.6源码分析

    《jQuery 1.2.6 源码分析》 jQuery是JavaScript库的里程碑之作,它的出现极大地简化了网页的DOM操作,事件处理,动画设计和Ajax交互。本篇文章将聚焦于jQuery 1.2.6版本的源码,深入剖析其内部机制,帮助开发者更好...

    Jquery1.2.6源码分析+源代码

    综上所述,jQuery 1.2.6 的源码分析涵盖了选择器引擎的实现、DOM 操作、事件处理、动画效果、AJAX 请求、扩展性等多个方面,对于深入理解 JavaScript 库的构建和优化具有重要意义。通过深入学习,开发者不仅能提升...

Global site tag (gtag.js) - Google Analytics