jQuery源码剖判,jQuery中绑定事件的两种方法
分类:pc28.am

jQuery function 参数传递

 

jQuery中绑定事件的几种方法

以click事件为例,jQuery中绑定事件有三种方法:

(1)target.click(function(){});

(2)target.bind("click",function(){});

(3)target.live("click",function(){});

第一种方法很好理解,其实就和普通JS的用法差不多,只是少了一个on而已

第二、三种方法都是绑定事件,但是二者又有很大的不同,下面着重讲解一下,因为这个如果用到Jquery的框架的话是用的挺多的,尤其要注意二者的区别。

【bind和live的区别】

live方法其实是bind方法的变种,其基本功能就同bind方法的功能是一样的,都是为一个元素绑定某个事件,但是bind方法只能给当前存在的元素绑定事件,对于事后采用JS等方式新生成的元素无效,而live方法则正好弥补了bind方法的这个缺陷,它可以对后生成的元素也可以绑定相应的事件。那么live方法的这个特性是怎么实现的呢?下面来探讨一下其实现原理。

live方法之所以能对后生成的元素也绑定相应的事件的原因归结在“事件委托”上面,所谓“事件委托”就是指绑定在祖先元素上的事件可以在其后代元素上进行使用。live方法的处理机制就是把事件绑定在DOM树的根节点上,而不是直接绑定在某个元素上。举一个例子来说明:

$(".clickMe").live("click",fn);

$("body").append("

测试live方法的步骤

");

 

当我们点击这个新增的元素时会依次发生如下步骤:

(1)生成一个click事件,传递给div来做处理

(2)由于没有事件直接绑定在div上,所以事件直接冒泡到DOM树上

(3)事件不断冒泡,直到DOM树的根节点上,默认情况下,根节点上就绑定了这个click事件

(4)执行由live绑定的click事件

(5)检测绑定事件的对象是否存在,判断是否需要继续执行绑定的事件。检测事件对象是通过检测

$(event.target).closest('.clickMe') 能否找到匹配的元素来实现的。

(6)通过(5)的测试,如果绑定事件的对象存在的话,就执行绑定的事件。

由于只有在事件发生的时候,live方法才会去检测绑定事件的对象是否存在,所以live方法可以实现后来新增的元素也可实现事件的绑定。相比之下,bind会在事件在绑定阶段就会判断绑定事件的元素是否存在,而且只针对当前元素进行绑定,而不是绑定到父节点上。

根据上面的分析,live的好处真是很大,那么为什么还要使用bind方法呢?之所以jquery要保留bind方法而不是采用live方法去替代bind,也是因为live在某些情况下是不能够完全替代bind的。主要的不同如下:

(1)bind方法可以绑定任何JavaScript的事件,而live方法在jQuery1.3的时候只支持click, dblclick, keydown, keypress,

keyup,mousedown, mousemove, mouseout, mouseover, 和 mouseup.在jQuery 1.4.1中,甚至也支持 focus 和 blue

事件了(映射到更合适,并且可以冒泡的focusin和focusout上)。另外,在jQuery 1.4.1中,也能支持hover(映射

到"mouseenter mouseleave")。

(2)live() 并不完全支持通过DOM遍历的方法找到的元素。取而代之的是,应当总是在一个选择器后面直接使用 .live()

方法。

(3)当一个元素采用live方法进行事件的绑定的时候,如果想阻止事件的传递或冒泡,就要在函数中return false,仅仅调

pc28.am,用stopPropagation()是无法实现阻止事件的传递或者冒泡的

 

以click事件为例,jQuery中绑定事件有三种方法: (1)target.click(function(){}); (2)target.bind(click,function(){}); (3)...

在开始正文之前,我想说明一个问题,也在在 拙作 我所理解的jQuery(2) 中网友的 讨论的话题--很多人认为 jQuery是一个"JavaScript框架". 对于这个观点,我表示不能苟同,仔细翻阅我的文章1和文章2,我一直都没有提到过"框架"这个概念;并且我又到官方站点jQuery.com上,仔细收索了一遍,从头到尾,也是没有发现他们在使用Framework这个字眼,同时还在其首页非常重要的位置发现了如下一句话"jQuery is a new kind of JavaScript Library."--没错,笔者自始至终地认为 jQuery是一种非常不错的JavaScript类库,正像官方宣言的那样.

jQuery的function函数中使用外部变量:

作者:nuysoft/JS攻城师/高云 QQ:47214707 EMail:[email protected]    

国学认为"无极生太极,太极生两仪,两仪生四象,四象生八卦,八卦生六十四卦",这个世界首先是一片混沌,然后有了"太极",然后由"太极"再逐渐演变成世间万物.那么我们讨论jQuery也从其"太极"--构建的方式说起.

//如何取得i的变量for { $.get("/test.html", function;}//使用闭包:for { { $.get("/test.html", function }); })}

 

在jQuery代码的最开始

JavaScript、jQuery 检测某 function 是否存在

后文预告:封装事件对象 便捷接口解析  

jQuery = window.jQuery = window.$ = function(selector, context) {
        return new jQuery.fn.init(selector, context);
    }

JavaScript 中检测某 function 是否存在的方法为:

 

这样定义了一个名称为jQuery的function,同时将这个function赋给window的成员window.jQuery和window.$. 请注意 这个function将会作为一个普通的方法(关于function的作用:普通方法/类型构造器 的辨析请参考笔者的第一片文章)(当然这个function也会作为类型使用,不过目前其是作为普通方法使用,关于jQuery这个function的辨析,请看本文最后的附文),暴露出来,让Web程序员在开发时调用,这个也是我们使用 jQuery的入口点,如下:

if(typeof $form.validate == 'function') { console.log;} else { console.log;}

前记:  

$(document).doSomething();

例如: 需要检测一个 MD5 方法是否存在:

JavaScript同其他语言一样,基础非常重要,仅仅会用框架和工具写一些WebApp是不能成为一名合格的JS工程师的,建议多读几次JavaScript权威指南,以我的经验与Java相比,JavaScript需要花费与Java相当的时间才能达到与Java相当的水平。  

$("#mySpan").doSomething();

if(typeof window.md5 == 'function') { // 如果纯在该方法,才去调用 md5;}

 

等.

而检测一个 jQuery 方法是否存在,可用一下方法:

jQuery完结之后计划写Java开源框架的源码解析,从Spring、Hibernate开始,有兴趣的同学可以一起研究。

在这个方法体内,我们看到其 通过new关键字构造了一个 jQuery.fn.init类型的实例.那么我们就逐步解读jQuery原型对象内的这个类型(因为jQuery.fn=jQuery.prototype,所以我们说这是一个原型对象内的类型).

if( jQuery.isFunction ) { // 如果该方法存在,才去调用 jQuery.rtFunction();}

JavaScript同其他语言一样,基础非常重要,仅仅会用框架和工具写一些WebApp是不能成为一名合格的JS工程师的,建议多读几次JavaScript权威指南,以我的经验与Java相比,JavaScript需要花费与Java相当的时间才能达到与Java相当的水平。

jQuery的原型对象定义的比较长(在1.3版本中,从25行一直到525行,共计500行),原型内的init()方法,也不算太短.

 

1.这个方法有两个参数 一个是选择器对象,一个选择器所在的环境(即在DOM的哪个部分去 查找这个选择器对象).不过我们开发人员使用的时候很少传递第二个参数(如果不传递第二参数,其会默认为document,即在整个文档内查找).

jQuery完结之后计划写Java开源框架的源码解析,从Spring、Hibernate开始,有兴趣的同学可以一起研究。Js代码 

2.方法体内首先判断 是否给这个方法传入了相应 选择器对象

10.8    DOM ready  

selector = selector || document;

 

通过这样确保selector对象是存在的--如果没有通过参数传入selector,那么就把document作为selector,这也就是我们看到很多介绍jQuery入门的文章提到几种使用jQuery选择器中的一种方式,即$()就代表$(document). (不知道大家是否真的理解了JavaScript中的操作符"||","&&"以及"!",你看一下本文的附注2,也许能有点好处.)

初学jQuery时,很可能学到的第一个知识点就是.ready(),但是网络上流转的文章和API对此的解释或剖析,经常是模棱两可甚至是不准确或错误的,本节将详细的阐述.ready()的用法和原理,并纠正这些误区。  

 

 

[******非常抱歉本来还有很多内容,但鉴于时间的关系,这个内容没有写完**************]

10.8.1  如何使用.ready()  

[****因为临时有事,同时本系列文章,可能也通过这种方式还在才刚刚开始的时候就忽然的终结,对关注这系列的朋友,sorry**********]

 

 

.ready() 指定一个事件句柄,当DOM完全加载完成时执行  

附1:关于jQuery 这个"关键字"的辨析

 

在jQuery的代码逻辑中,jQuery这几个字母,其在不同地方使用,是指代不同的角色的.

虽然JavaScript提供了load事件,当页面渲染完成之后会执行这个函数,在所以元素加载完成之前,这个函数不会被调用,例如图像。但是在大多数情况下,只要DOM结构加载完,脚本就可以尽快运行。传递给.ready()的事件句柄在DOM准备好后立即执行,因此通常情况下,最好把绑定事件句柄和其他jQuery代码都到这里来。但是当脚本依赖于CSS样式属性时,一定要在脚本之前引入外部样式或内嵌样式的元素。  

a.一个普通方法.在我们日常开发中,使用jQuery(或者$) 选择页面元素的时候($("#mySpan")), jQuery他就是一个普通的方法,这个在正文中也提及.

 

b.一个类型实例.本来这个function是一个普通方法,但是这个方法内部 return了一个new后的对象,因此,jQuery也表示一个对象实例.(其实更准确的说jQuery表示的是jQuery.fn.init这个类型的实例,因为我们看到在这个function内通过new关键字

如果代码依赖于需加载完的元素(例如,想获取一个图片的尺寸大小),应该用.load()事件代替,并把代码放到load事件句柄中。  

操作的就是jQuery.fn.init这个类型,但是后面的代码中,又有这么一句jQuery.fn.init.prototype

jQuery.fn,即把jQuery的原型对象赋给了jQuery.fn.init的原型对象,因此我们就可以近似的认为 这个function返回的就是jQuery的类型实例了)

c.一个类型.正像 第一片文章中说的那样,任何function都会有两个角色.因此这个地方 jQuery也是类型.我们很多地方 使用了 如下这样的方式 $.doSomething(),那么其实是把jQuery做为类型在使用了,我们这样使用($.doSomething()),其实是使用了这个类型的静态方法.

jQuery究竟是代表一个 普通方法,还是一个类型,抑或是 一个类型实例,这个还要看具体使用的环境,也只有当我们能完全清楚了jQuery在其上下文中充当的角色后,我们才能更容易理解jQuery的代码逻辑.

附注2:也许是你不知道的JavaScript的操作符的用法

a.操作符"||". 如果对几个对象同时进行"||"操作的时候,JavaScript首先将这些对象 转换成 true和false,然后在进行"||", 这个很重要. 那么什么对象转换成true,什么对象转换成false呢? 首先关键字true和false会进行本义的转换这个没有问题. 接着如果一个对象 是存在的(不是undefined,不是null),那么这个对象就会转成true,否则就为false. 在同时进行&&操作的几个对象进行计算的时候,顺序从左到右,碰到第一为true的对象后,就把这个对象 返回(把剩下还没有判断的对象忽略).返回的时候,不是返回true或者false,而是返回这个对象自身,如下:

(function(passedObj) {
            var existedObj = {};
            var validObject = null ||false ||passedObj || "validString" || existedObj;
            alert(validObject);
        })();

(其中passedObj是一个 "需要"传入的参数,实际调用的时候,并没有传入,因此其必定为undefined)

那么其将会弹出 第一为true的对象,即 validString.

b.操作符 "&&" 道理亦然.只是碰到第一为 false的对象返回,同时忽略剩下还没有判断的对象.

c.操作符"!" 这就简单了,将要判断的对象 转成 true或false后,然后取反.其返回的是true或false.

 

.ready()方法不同于<body onload="">属性。如果必须用load事件,那么就不要使用.ready(),或用.load()代替,把load事件句柄绑定到window或其他的具体元素上,例如图片。  

 

以下三个语法全部是等价的:  

$(document).ready(handler)  

$().ready(handler) (this is not recommended)  

$(handler)  

 

$(document).bind("ready", handler)的行为类似于ready方法,但有一个例外:如果ready事件已触发后,再尝试用.bind("ready")绑定的处理函数将不会被执行。而用以上三种方法绑定的句柄会被执行,无论是什么时候绑定的。  

.ready()方法只能在包含了document的jQuery上调用,因此选择器可以省略。  

.ready()方法典型的用法是使用一个匿名函数:  

$(document).ready(function() {  

  // Handler for .ready() called.  

});  

等价于:  

$(function() {  

 // Handler for .ready() called.  

});  

 

如果在DOM加载完毕之后调用.ready(),新的句柄将会立即执行。  

 

特别强调两点:  

1.  之所以花费篇幅来阐述.ready()如何使用(翻译的官网文档),是因为网络上的一些文章和中文API不准确甚至是错误的(应该是工具翻译的),所以需谨慎参考  

2.  .ready()的触发要早于.load(),但是不要完全迷信依赖,如果要获取或操作样式,或依赖于像图片这样的必须加载完成才能获取和操作的元素,就用<body onload="">或.load()  

 

10.8.2  源码分析  

 

到底.ready()是如何实现更快的触发ready事件的呢,关键在jQuery.bindReady方法的实现里:  

 

对标准浏览器绑定:document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );  

对IE浏览器绑定:document.attachEvent( "onreadystatechange", DOMContentLoaded );  

 

当然还有一些其他的关键技巧,现在完成的看下jQuery.bindReady的实现:  

 

// 绑定DOM ready监听器,跨浏览器,兼容标准浏览器和IE浏览器  

bindReady: function() { // jQuery.bindReady  

if ( readyList ) {  

    return;  

}  

 

readyList = jQuery._Deferred(); // 初始化ready异步事件句柄队列  

 

// Catch cases where $(document).ready() is called after the  

// browser event has already occurred.  

// 如果DOM已经完毕,立即调用jQuery.ready  

if ( document.readyState === "complete" ) {  

    // Handle it asynchronously to allow scripts the opportunity to delay ready  

    // 重要的是异步  

    return setTimeout( jQuery.ready, 1 );  

}  

 

// Mozilla, Opera and webkit nightlies currently support this event  

// DOM 2级事件模型,Mozilla, Opera, webkit等   

if ( document.addEventListener ) {  

    // Use the handy event callback  

    // 使用快速事件句柄  

    document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );  

 

    // A fallback to window.onload, that will always work  

    // 再在window上绑定load事件句柄,这个句柄总是会执行  

    // 为什么同时绑定document window呢?我想是为了安全起见,防御性编码!  

    window.addEventListener( "load", jQuery.ready, false );   

 

// If IE event model is used  

} else if ( document.attachEvent ) {  

    // ensure firing before onload,  

    // maybe late but safe also for iframes  

    // 同样onreadystatechange会在onload之前触发,但是对于iframe会有延迟但安全一定会触发  

    // 看看DOMContentLoaded的实现,是检测document.readyState的状态是否为complete,这里有些像ajax中的检测   

    document.attachEvent( "onreadystatechange", DOMContentLoaded );  

 

    // A fallback to window.onload, that will always work  

    window.attachEvent( "onload", jQuery.ready ); // 同样的安全起见,防御性编码!及时前边的所以hack技巧失败了,onload是最后的保障  

 

    // If IE and not a frame  

    // continually check to see if the document is ready  

    var toplevel = false;  

 

    try {  

        toplevel = window.frameElement == null; // 检查window的frameElement属性,看是否是顶层窗口  

    } catch(e) {}  

      

    // 做doScroll检测,如果在iframe中就不检测了,onreadystatechange对于ifame很可靠  

    if ( document.documentElement.doScroll && toplevel ) {  

        doScrollCheck();   

        // 在doScrollCheck中,不断的(每隔1ms)执行document.documentElement.doScroll("left"),直到不抛出异常为止  

        // 这是IE下检测DOM ready的技巧  

        }  

    }  

},  

 

然后是完整的ready相关方法的分析,我剔除了其他无关的代码,保留了整体结构和相关方法:  

 

(function( window, undefined ) {  

 

    var jQuery = (function() {  

          

        // Define a local copy of jQuery  

        var jQuery = function( selector, context ) {  

                // The jQuery object is actually just the init constructor 'enhanced'  

                var ret = new jQuery.fn.init( selector, context, rootjQuery );  

                return ret;  

            },  

          

            // A central reference to the root jQuery(document)  

            rootjQuery, // 包含了document的jQuery对象  

          

            // The deferred used on DOM ready  

            readyList, // ready事件处理函数队列  

          

            // The ready event handler  

            DOMContentLoaded, // DOM ready hack句柄,.ready()能早于.load()的关键所在  

          

        jQuery.fn = jQuery.prototype = {  

            constructor: jQuery,  

            init: function( selector, context, rootjQuery ) {  

                // HANDLE: $(function)  

                // Shortcut for document ready  

                // 如果函数,则认为是DOM ready句柄  

                if ( jQuery.isFunction( selector ) ) {  

                    return rootjQuery.ready( selector );  

                }  

            },  

          

            ready: function( fn ) {  

                // Attach the listeners  

                jQuery.bindReady(); // 绑定DOM ready监听器,跨浏览器,兼容标准浏览器和IE浏览器  

          

                // Add the callback  

                readyList.done( fn ); // 将ready句柄添加到ready异步句柄队列  

          

                return this;  

            }  

        };  

          

        // Give the init function the jQuery prototype for later instantiation  

        jQuery.fn.init.prototype = jQuery.fn;  

          

        jQuery.extend = jQuery.fn.extend = function() {};  

          

        jQuery.extend({  

          

            // Is the DOM ready to be used? Set to true once it occurs.  

            // DOM是否加载完毕  

            isReady: false,  

          

            // A counter to track how many items to wait for before  

            // the ready event fires. See #6781  

            // DOM加载完毕之前的等待次数  

            readyWait: 1,  

          

            // Hold (or release) the ready event  

            // 是否延迟触发DOM ready?在jQuery中没有任何地方有调用到holdReady,这是个遗留方法还是预留方法,有待继续研究。  

            // 因此在当前版本中,readyWait总是1,直到自减  

            holdReady: function( hold ) {  

                if ( hold ) { // 继续等待  

                    jQuery.readyWait ;  

                } else {  

                    jQuery.ready( true ); //   

                }  

            },  

          

            // Handle when the DOM is ready  

            // 判断DOM是否加载完毕,如果已完毕,调用DOM ready事件异步队列readyList,如果未完,每个1ms检查一次  

            ready: function( wait ) { // jQuery.ready  

                // Either a released hold or an DOMready/load event and not yet ready  

                // 条件1:wait === true && !--jQuery.readyWait 还在等待加载完成,但是等待计数器jQuery.readyWait已经是0,  

                // 换句话说参数wait为true表示尝试一下看是否能开始调用readyList了,如果发现计数器jQuery.readyWait变成0,啥也不管了,开始调用吧  

                // 再换句话说,计数器已经是0了,开干吧  

                  

                // 条件2:wait !== true && !jQuery.isReady 明确的说不用了,即使DOM ready标记还是false  

                // 换句话说,及时DOM ready标记还是false,但是调用jQuery.ready的客户端认为不比再等了,可以开干了  

                if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {  

                    // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).  

                    // 检查document.body是否存在,这是特定于IE的检测,保证在IE中DOM ready事件能正确判断  

                    if ( !document.body ) {  

                        return setTimeout( jQuery.ready, 1 );  

                    }  

 

                    // Remember that the DOM is ready  

                    // 到这里,jQuery.isReady被强制为true  

                    // 在条件2中,如果jQuery.isReady为true,那么说明readyList的状态已经确定,添加到readyList中的函数会被立即执行  

                    // 如果jQuery.isReady为是false,那么接下来readyList中函数将被执行  

                    jQuery.isReady = true;  

 

                    // If a normal DOM Ready event fired, decrement, and wait if need be  

                    // 虽然上边的条件2的意思是,别管其他情况,调用方认为ready了,但是这里仍然做了防御性检测,如果等待计数器仍然大于1,结束ready调用  

                    // 如果这个条件成立,那么一定是哪里出问题了!  

                    // 在当前版本1.6.1中,这个判断永远不会成立,因为没有地方调用会使readyWait加一的holdReady  

                    if ( wait !== true && --jQuery.readyWait > 0 ) {  

                        return;  

                    }  

 

                    // If there are functions bound, to execute  

                    // 调用DOM ready事件异步队列readyList,注意整理的参数亮了!  

                    // document指定了ready句柄的上下文,这样我们在执行ready事件句柄时this指向document  

                    // [ jQuery ]指定了ready事件句柄的第一个参数,这样即使调用$.noConflict()交出了$的控制权,我们依然可以将句柄的第一个参数命名为$,继续在句柄内部使用$符号  

                    // 如此的精致!赞叹之余,但不要在你的项目中也这么用,理解和维护将成为最大的难题。  

                    readyList.resolveWith( document, [ jQuery ] );  

 

                    // Trigger any bound ready events  

                    if ( jQuery.fn.trigger ) {  

                        // 触发ready事件,然后删除ready句柄,DOM ready事件只会生效一次,ready是个自定义事件  

                        jQuery( document ).trigger( "ready" ).unbind( "ready" );  

                    }  

                }  

            },  

          

            // 绑定DOM ready监听器,跨浏览器,兼容标准浏览器和IE浏览器  

            bindReady: function() { // jQuery.bindReady  

                if ( readyList ) {  

                    return;  

                }  

 

                readyList = jQuery._Deferred(); // 初始化ready异步事件句柄队列  

 

                // Catch cases where $(document).ready() is called after the  

                // browser event has already occurred.  

                // 如果DOM已经完毕,立即调用jQuery.ready   

                if ( document.readyState === "complete" ) {  

                    // Handle it asynchronously to allow scripts the opportunity to delay ready  

                    // 重要的是异步  

                    return setTimeout( jQuery.ready, 1 );  

                }  

 

                // Mozilla, Opera and webkit nightlies currently support this event  

                // DOM 2级事件模型,Mozilla, Opera, webkit等   

                if ( document.addEventListener ) {  

                    // Use the handy event callback  

                    // 使用快速事件句柄  

                    document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );  

 

                    // A fallback to window.onload, that will always work  

                    // 再在window上绑定load事件句柄,这个句柄总是会执行  

                    // 为什么同时绑定document window呢?我想是为了安全起见,防御性编码!  

                    window.addEventListener( "load", jQuery.ready, false );   

 

                // If IE event model is used  

                } else if ( document.attachEvent ) {  

                    // ensure firing before onload,  

                    // maybe late but safe also for iframes  

                    // 同样onreadystatechange会在onload之前触发,但是对于iframe会有延迟但安全一定会触发  

                    // 看看DOMContentLoaded的实现,是检测document.readyState的状态是否为complete,这里有些像ajax中的检测   

                    document.attachEvent( "onreadystatechange", DOMContentLoaded );  

 

                    // A fallback to window.onload, that will always work  

                    window.attachEvent( "onload", jQuery.ready ); // 同样的安全起见,防御性编码!及时前边的所以hack技巧失败了,onload是最后的保障  

 

                    // If IE and not a frame  

                    // continually check to see if the document is ready  

                    var toplevel = false;  

 

                    try {  

                        toplevel = window.frameElement == null; // 检查window的frameElement属性,看是否是顶层窗口  

                    } catch(e) {}  

                      

                    // 做doScroll检测,如果在iframe中就不检测了,onreadystatechange对于ifame很可靠  

                    if ( document.documentElement.doScroll && toplevel ) {  

                        doScrollCheck();   

                        // 在doScrollCheck中,不断的(每隔1ms)执行document.documentElement.doScroll("left"),直到不抛出异常为止  

                        // 这是IE下检测DOM ready的技巧  

                    }  

                }  

            },  

        });  

          

        // All jQuery objects should point back to these  

        rootjQuery = jQuery(document);  

          

        // Cleanup functions for the document ready method  

        // 构造浏览器加载完毕事件处理函数DOMContentLoaded,需要检测浏览器添加事件的方法  

        if ( document.addEventListener ) {  

            DOMContentLoaded = function() {  

                // document ready之后移除  

                document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );  

                jQuery.ready();  

            };  

          

        } else if ( document.attachEvent ) {  

            DOMContentLoaded = function() {  

                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).  

                // 确保body是存在的,IE会有一些延迟  

                if ( document.readyState === "complete" ) {  

                    // 先移除,难道浏览器重新渲染会再次触发onreadystatechange吗?  

                    document.detachEvent( "onreadystatechange", DOMContentLoaded );  

                    jQuery.ready();  

                }  

            };  

        }  

          

        // The DOM ready check for Internet Explorer  

        // 在IE里,每隔1ms检测IE浏览器的ready状态  

        function doScrollCheck() {  

            if ( jQuery.isReady ) {  

                return;  

            }  

          

            try {  

                // If IE is used, use the trick by Diego Perini  

                //   

                // 如果是IE,则使用该技巧来检测浏览器加载状态  

                document.documentElement.doScroll("left");  

            } catch(e) {  

                setTimeout( doScrollCheck, 1 );  

                return;  

            }  

          

            // and execute any waiting functions  

            // 执行其他的等待函数  

            jQuery.ready();  

        }  

          

        // Expose jQuery to the global object  

        return jQuery;  

      

    })();  

 

    // 见系列文章中关于异步队列的解析  

    jQuery.extend({  

        // Create a simple deferred (one callbacks list)  

        _Deferred: function() {},  

      

        // Full fledged deferred (two callbacks list)  

        Deferred: function( func ) {},  

      

        // Deferred helper  

        when: function( firstParam ) {}  

    });  

      

    // 见系列文章中关于事件的解析  

    jQuery.event = {  

        trigger: function( event, data, elem, onlyHandlers ) {},  

 

        handle: function( event ) {},  

 

        special: {  

            ready: {  

                // Make sure the ready event is setup  

                setup: jQuery.bindReady,  

                teardown: jQuery.noop  

            }  

        }  

    };  

 

    window.jQuery = window.$ = jQuery;  

})(window);   

QQ:47214707 EMail:[email protected] 后文预告:封装事件对象 便捷接口解析 前记: JavaScript同其他语言一样,基础非...

本文由pc28.am发布于pc28.am,转载请注明出处:jQuery源码剖判,jQuery中绑定事件的两种方法

上一篇:表单脚本 下一篇:没有了
猜你喜欢
热门排行
精彩图文