• jQuery1.2.1架构分析初始化


     

      当页面加载jQuery脚本后,jQuery就开始了自己的初始化过程:创建jQuery以及jQuery的构造和原型函数并等待调用。让我们分析一下这个过程:

    1.首先,检查jQuery和$是否已定义(避免和其它javascript框架的冲突,这意味着为了避免冲突,你应该让其它的框架应早于jQuery加载),将其进行重命名为_jQuery和_$.并定义jQuery的别名为$。
    看到这里,你应该明白,对于其它冲突的框架(主要是$的冲突),我们可以通过_$进行访问。
    实际上,为了更加方便,jQuery还提供了一个noConflict方法,这个方法恢复了原有冲突的框架的_$为$,并返回jQuery方法以便于你重新命名。这样,对于jQuery框架,你使用jQuery代替$进行访问,对于其它框架,则通过$符号进行访问。
    jQuery.noConflict=function(deep) {
    window.$ = _$;
      /*如果deep为true,jQuery也被替换了*/
    if ( deep )
    window.jQuery = _jQuery;
    return jQuery;
    }
    让我们举个例子:
    <html>
    <head>
      <script src="prototype.js"></script>
      <script src="jquery.js"></script>
      <script>
        jQuery.noConflict();
        // Use jQuery via jQuery(...)
        jQuery(document).ready(function(){
        jQuery("div").hide();
        });
        // Use Prototype with $(...), etc.
        $('someid').style.display = 'none';
      </script>
    </head>
    <body></body>
    </html>
    更详细的说明你可以参阅http://docs.jquery.com/Using_jQuery_with_Other_Libraries,详细的说明了如何避免不同框架的冲突。
    还是让我们看一下这个步骤的具体的代码:
    if ( typeof jQuery != "undefined" )
    var _jQuery = jQuery;
    ...  
    if ( typeof $ != "undefined" )
      var _$ = $;
    window.$ = jQuery;

    2.定义jQuery的构造和原型函数,这个过程同时定义了prototype的别名为fn:jQuery.prototype=jQuery.fn。jQuery的原型prototype在这里隆重的出场了,jQuery对象的原型prototype包括了诸多的核心方法和属性:
    init
    jquery 当前的版本号
    size 返回了length属性
    length
    get
    pushStack
    each
    ...

    3.定义了evalScript函数

    4.extend方法终于隆重登场了

    5.定义了一个非常重要的属性名expando,如果后续的jQuery对象需要进行缓存,则对象会被赋予以该属性命名的属性,该属性的值为一个递增的uuid值(具体的内容可以参阅data方法)。
      var expando = "jQuery" + (new Date()).getTime();

    6现在开使用extend方法来定义jQuery的诸多方法。
    注意,不是定义jQuery对象的方法,因为这些方法只能通过诸如jQuery.noconflict()的形式调用。这些方法包括:
    noconflict
    isFunction
    isXMLDoc
    globalEval
    each
    map
    ...

    6开始识别浏览器以及其特性
    var userAgent = navigator.userAgent.toLowerCase();
    jQuery.browser = {
      version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
      safari: /webkit/.test(userAgent),
      opera: /opera/.test(userAgent),
      msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
      mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
    };
    var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
    jQuery.extend({
      boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
      styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
      props: {
        "for": "htmlFor",
        "class": "className",
        "float": styleFloat,
        cssFloat: styleFloat,
        styleFloat: styleFloat,
        innerHTML: "innerHTML",
        className: "className",
        value: "value",
        disabled: "disabled",
        checked: "checked",
        readonly: "readOnly",
        selected: "selected",
        maxlength: "maxLength"
      }
    })
    7.通过each方法,非常灵巧简化的实现了诸多方法:
    jQuery.each({
    parent: "a.parentNode",
    parents: "jQuery.dir(a,'parentNode')",
    next: "jQuery.nth(a,2,'nextSibling')",
    prev: "jQuery.nth(a,2,'previousSibling')",
    nextAll: "jQuery.dir(a,'nextSibling')",
    prevAll: "jQuery.dir(a,'previousSibling')",
    siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
    children: "jQuery.sibling(a.firstChild)",
    contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"
    }, function(i,n){
    jQuery.fn[ i ] = function(a) {
    var ret = jQuery.map(this,n);
    if ( a && typeof a == "string" )
    ret = jQuery.multiFilter(a,ret);
    return this.pushStack( jQuery.unique(ret) );
    };
    });
    jQuery.each({
      appendTo: "append",
      prependTo: "prepend",
      insertBefore: "before",
      insertAfter: "after",
      replaceAll: "replaceWith"
    }, function(i,n){
      jQuery.fn[ i ] = function(){
        var a = arguments;
        return this.each(function(){
          for ( var j = 0, al = a.length; j < al; j++ )
            jQuery(a[j])[n]( this );
        });
      };
    });

    jQuery.each( {
      removeAttr: function( key ) {
        jQuery.attr( this, key, "" );
        this.removeAttribute( key );
      },
      addClass: function(c){
        jQuery.className.add(this,c);
      },
      removeClass: function(c){
        jQuery.className.remove(this,c);
      },
      toggleClass: function( c ){
        jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
      },
      remove: function(a){
        if ( !a || jQuery.filter( a, [this] ).r.length ) {
          jQuery.removeData( this );
          this.parentNode.removeChild( this );
        }
      },
      empty: function() {
        // Clean up the cache
        jQuery("*", this).each(function(){ jQuery.removeData(this); });

        while ( this.firstChild )
          this.removeChild( this.firstChild );
      }
    }, function(i,n){
      jQuery.fn[ i ] = function() {
        return this.each( n, arguments );
      };
    });

    jQuery.each( [ "Height", "Width" ], function(i,name){
      var n = name.toLowerCase();
      jQuery.fn[ n ] = function(h) {
        return this[0] == window ?
          jQuery.browser.safari && self["inner" + name] ||
          jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) ||
          document.body["client" + name] :
          this[0] == document ?
            Math.max( document.body["scroll" + name], document.body["offset" + name] ) :
            h == undefined ?
              ( this.length ? jQuery.css( this[0], n ) : null ) :
              this.css( n, h.constructor == String ? h : h + "px" );
      };
    });
    8.通过extend方法,为jQuery类添加了解析表达式部分的方法:
    var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
    "(?:[\\w*_-]|\\\\.)" :
    "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
    quickChild = new RegExp("^>\\s*(" + chars + "+)"),
    quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
    quickClass = new RegExp("^([#.]?)(" + chars + "*)");
    jQuery.extend({
    expr: {
    "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
    "#": "a.getAttribute('id')==m[2]",
    ...
    9.现在,定义jQuery.event对象:
    jQuery.event = {
    add: function
    guid:1,
    global:{}
    remove:function
    trigger:function
    handle:function
    fix:function
    }

    10开始定义jQuery对象的事件相关的方法
    jQuery.fn.extend({
    bind:function
    one:function
    ...
    })

    11定义了jQuery的启动(dom load)的处理方法
    jQuery.extend({
      isReady:false
      readyList:[]
      ready:function(){}
    }

    12通过each方法,非常技巧的实现了绑定事件的处理
    jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
    "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
    "submit,keydown,keypress,keyup,error").split(","), function(i,o){
      jQuery.fn[o] = function(f){
        return f ? this.bind(o, f) : this.trigger(o);
      };
    });

    13定义bindReady方法

    14开始实现jQuery对象的ajax方法

    15.通过each方法,非常技巧的实现了绑定ajax事件的处理
    jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
      jQuery.fn[o] = function(f){
        return this.bind(o, f);
      };
    });

    16开始实现jQuery类的ajax方法

    17jQuery对象的show hide等界面效果方法的定义

    18queue函数的定义
    var queue = function( elem, type, array ) {
      if ( !elem )
        return;
      var q = jQuery.data( elem, type + "queue" );
      if ( !q || array )
        q = jQuery.data( elem, type + "queue",
          array ? jQuery.makeArray(array) : [] );
      return q;
    };

    19jQuery对象的dequeu方法的实现
    jQuery.fn.dequeue = function(type){
      type = type || "fx";

      return this.each(function(){
        var q = queue(this, type);

        q.shift();

        if ( q.length )
          q[0].apply( this );
      });
    };
    20.jQuery类的speed方法、easing对象、timers数组和fx构建器的定义

    21jQuery.fx的原型函数prototype的定义的实现

    22jQuery.fx.step对象的定义

    23.jQuery.offset方法的实现

  • 相关阅读:
    Python3练习题 026:求100以内的素数
    【Python3练习题 025】 一个数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同
    Python3练习题 022:用递归函数反转字符串
    Python3练习题 021:递归方法求阶乘
    【Python3练习题 020】 求1+2!+3!+...+20!的和
    【Python3练习题 019】 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
    Python3练习题 018:打印星号菱形
    Python3练习题 006 冒泡排序
    【Python3练习题 017】 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比。请编程序找出三队赛手的名单。
    【Python3练习题 016】 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
  • 原文地址:https://www.cnblogs.com/rooney/p/1346021.html
Copyright © 2020-2023  润新知