zoukankan      html  css  js  c++  java
  • jQuery基本框架解析

    我们研究一下jQuery的源码

    编码方法很简单。 下面是全部代码的开头和结尾。

    (function( window, undefined ) {
     
    var document = window.document,
        navigator = window.navigator,
        location = window.location;
     
        [...] // The main sources are here
         
    window.jQuery = window.$ = jQuery;
    })(window);
    

      

    核心

     下面是主要代码的缩减版,可以看到很多块代码。

    var jQuery = (
          function () {   
    var jQuery = function ( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery );};     // Map over jQuery in case of overwrite    _jQuery = window.jQuery,     // Map over the $ in case of overwrite    _$ = window.$,    // A central reference to the root jQuery(document)    rootjQuery,    [...]       rootjQuery = jQuery(document);    [...]    return jQuery; })();

    上面代码中jQuery对象的构造函数, jQuery、$和 rootjQuery(一个指向文档的jQuery对象)。

    下面代码解释为什么我们可以用"."和"[]"操作变量jQuery对象。

    trim = String.prototype.trim,
    indexOf = Array.prototype.indexOf,

     对象的构造

    这里是jQuery函数的最神圣的地方。jQuery的prototype的魔力隐藏在这里。

    var jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    },

    当你调用jQuery函数式,紧接着新建一个“jQuery.fn.init” 对象并返回。 参看下面代码:

    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function( selector, context, rootjQuery ) {
            [...]
        }
        [...]
    }
     
    // Give the init function the jQuery prototype for later instantiation
    jQuery.fn.init.prototype = jQuery.fn;
    至此, 我们可以知道jQuery.fn等同于jQuery prototype,同时,jQuery.fn.init.prototype指向jQuery prototype,  jQuery.fn.init.prototype constructor指向jQuery。这些信息给了我们一个有意思的结论:输入以下代码
    $(document) instanceof jQuery; // true
    $(document) instanceof jQuery.fn.init; // true

    为了帮助理解,请再看下面的例子:

    var Init = function () {
        console.log('[Init]');
    };
     
    var jQuery = function () {
        console.log('[jQuery]');
        return new Init();
    };
     
    Init.prototype = jQuery.prototype = {
        constructor: jQuery
    };
     
    var $elem = jQuery(); // [jQuery] , [Init]
     
    console.log( $elem instanceof jQuery ); // true
    console.log( $elem instanceof Init   ); // true

    可以看出,所有的结构都在一个jQuery.fn.init对象函数里,而jQuery是生产所有jQuery.fn.init对象的工厂。

     解析参数

    有很多种应用jQuery函数的方法:

    $(function () { alert('READY!') }); // Function to be executed only when loading a DOM
    $(document.getElementById('test')); // link on the element
    $('<div />'); // create new element
    $('<div />', { title: 'test' }); // create new element with attributes
     
    // Supports all imaginable and unimaginable css-selectors:
    $('#element'); // element with ip "element"
    $('.element', $previous ); // Find all elements with a class element in $ previous
    $("div[name=city]:visible:has(p)");

    让我们进一步分析jQuery.fn.init函数。

    init: function( selector, context, rootjQuery ) {
        if ( !selector ) return this;
     
        // Handle $(DOMElement)
        if ( selector.nodeType ) return this = selector;
     
        // The body element only exists once, optimize finding it
        if ( selector === "body" && !context ) return this = document.body;
     
        if ( jQuery.isFunction( selector ) ) {
            return rootjQuery.ready( selector );
        }
     
        // Handle HTML strings
        if ( typeof selector === "string" ) {
            // Verify a match, and that no context was specified for #id
            if ( selector.match(quickExpr) ) {
                if ( match[1] ) {
                    return createNewDomElement( match[1] );
                } else {
                    return getById( match[2] )
                }
            } else {
                return jQuery( context ).find( selector );
            }
        }
    },

    前面四小块代码很简单——当参数分别为空、DOM元素、“body”字符串时如何处理。

    Plug-ins Development  创建插件

    很多专业人士都知道js的类可以很简单地通过prototypes进行扩展。

    var MyClass = function () {
        // constructor
    };
     
    MyClass.prototype = {
        // prototype
    };
     
    var instance = new MyClass();
     
    // We can extend the class prototype and new features will be added to all entities, even those whichvare already created
     
    MyClass.prototype.plugin = function () {
        console.log("He's alive!");
    };
     
    instance.plugin(); // He's alive!

    我们可以用同样方法对标准JQuery进行扩展。

    jQuery.prototype.plugin = function () {
        // Here is my plugin
    };
    但是,我们已知fn等于jQuery.prototype,所以可以简写如下:
    jQuery.fn.plugin = function () {
        // Here is my plugin
        // This here refers to jquery-object, from which the method is called
    };

    因为插件会添加属性到所有已存在的实体和将来要新建的实体,所以如果想针对地对某一对象添加属性,可以用静态属性:

    jQuery.plugin = function () {
        // Here is my plugin
    };

    小插件的最佳模式:

    new function (document, $, undefined) {
         
        var privateMethod = function () {
            // private method, used for plugin
        };
         
        $.fn.myPlugin = function () {
             
        };
         
        // and if you need a method that is not bound to the dom-elements:
        $.myPlugin = function () {
             
        };
         
    }(document, jQuery);

     

  • 相关阅读:
    优先队列
    Problem W UVA 662 二十三 Fast Food
    UVA 607 二十二 Scheduling Lectures
    UVA 590 二十一 Always on the run
    UVA 442 二十 Matrix Chain Multiplication
    UVA 437 十九 The Tower of Babylon
    UVA 10254 十八 The Priest Mathematician
    UVA 10453 十七 Make Palindrome
    UVA 10163 十六 Storage Keepers
    UVA 1252 十五 Twenty Questions
  • 原文地址:https://www.cnblogs.com/liubingna/p/2957620.html
Copyright © 2011-2022 走看看