jQuery源码学习8——工具方法之init

接下来再回到init工具方法

总体看来init里面都是通过jQuery.each方法来遍历macros里面的各项

再将其扩展到jQuery.prototype下面作为实例方法

(1)、axis

jQuery.each( jQuery.macros.axis, function(i,n){
    jQuery.fn[ i ] = function(a) {
        var ret = jQuery.map(this,n);
        if ( a && a.constructor == String )
            ret = jQuery.filter(a,ret).r;
        return this.pushStack( ret, arguments );
    };
});
axis: {
    parent: "a.parentNode",
    ancestors: jQuery.parents,
    parents: jQuery.parents,
    next: "jQuery.sibling(a).next",
    prev: "jQuery.sibling(a).prev",
    siblings: jQuery.sibling,
    children: "a.childNodes"
},

遍历axis时,function里面i就是axis的键,例如parent ancestors

n就是axis里面键对应的值,例如"a.parentNode" jQuery.parents

其实就是将parent ancestors之类的方法扩展到了jQuery.fn(即jQuery.prototype)上了

axis扩展到jQuery.prototype上的方法都传入了一个参数a

接下来通过map方法遍历jQuery对象this

实际上this就是一个类数组对象

map方法的返回值ret存储的就是this里面的各项通过n处理后返回的结果

n又分为字符串和函数两类,通过字符串传入时就传入一个字符串格式的方法体就可以

这些细节都在map方法中已经处理好了

map和each一个很大的区别就是map内部重新定义了一个数组

再用传入的fn处理后push到这个数组里面

最后返回这个数组,这个数组和原来通过map方法处理的json或数组已经没有任何关系了

完全是两个不同的变量

在这里的话就是ret和this没有任何的关系了,之后再对ret修改也不会影响到this了

在调用parent这个方法的时候将会类似$("#div1").parent("xxx")或$("#div1").parent()

(2)to

        jQuery.each( jQuery.macros.to, function(i,n){
            jQuery.fn[ i ] = function(){
                var a = arguments;
                return this.each(function(){
                    for ( var j = 0; j < a.length; j++ )
                        $(a[j])[n]( this );
                });
            };
        });
    to: {
        appendTo: "append",
        prependTo: "prepend",
        insertBefore: "before",
        insertAfter: "after"
    },

总体和上面axis差不太多,以appendTo为例

实际上就是类似这样的扩展:

    jQuery.prototype.appendTo=function(){
        var a = arguments;
        return this.each(function(){
            for ( var j = 0; j < a.length; j++ )
                $(a[j])[n]( this );
        });
    };

这里的n其实就是"append"

调用的时候形如$("<div></div>").appendTo($("#div1"));

意思就是在$("#div1")下添加一个div

其实to里面扩展的方法都有一个"反向添加"的效果

(3)each

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

macros.each下面方法太多了,就不贴代码了

以removeAttr为例,扩展方法的形式为

    jQuery.prototype.removeAttr=function(){
        return this.each(function( key ) {
            this.removeAttribute( key );
        },arguments);
    };

在调用时就形如$("#div1").removeAttr("abc");

removeAttr函数体里面的arguments就会接收到"abc"这个参数

    this.each(function( key ) {
        this.removeAttribute( key );
    },["abc"]);

实例化方法的each最终会调用静态方法jQuery.each

    each: function( fn, args ) {
        return jQuery.each( this, fn, args );
    },

调用形式为

jQuery.each(this,function(key){
    this.removeAttribute(key);
},["abc"]);

最终传入的function会以以下这种方式调用,fn就是指传入的该函数

fn.apply(this[0],["abc"]);

其实这些方法之所以放到一个键叫each的对象当中,就是因为这些方法的内部都会调用each方法

(4)filter

        jQuery.each( jQuery.macros.filter, function(i,n){
            jQuery.fn[ n ] = function(num,fn) {
                return this.filter( ":" + n + "(" + num + ")", fn );
            };
        });
    filter: [ "eq", "lt", "gt", "contains" ],

这几个方法就是调用了Sizzle里面的伪类选择器来实现的,例如$(".div").eq(0)会就是要调用this.filter(":eq(0)");

(5)attr

        jQuery.each( jQuery.macros.attr, function(i,n){
            n = n || i;
            jQuery.fn[ i ] = function(h) {
                return h == undefined ?
                    this.length ? this[0][n] : null :
                    this.attr( n, h );
            };
        });
    attr: {
        val: "value",
        html: "innerHTML",
        id: null,
        title: null,
        name: null,
        href: null,
        src: null,
        rel: null
    },

attr里面每一项如果有值的话,这个值是对应的键的修正值,这几个方法都有设置和获取的功能

获取的话会调用attr实例化方法

(6)css

        jQuery.each( jQuery.macros.css, function(i,n){
            jQuery.fn[ n ] = function(h) {
                return h == undefined ?
                    ( this.length ? jQuery.css( this[0], n ) : null ) :
                    this.css( n, h );
            };
        });
css: "width,height,top,left,position,float,overflow,color,background".split(","),

css里面的各个方法底层自然是通过调用css原生方法来实现的

posted on 2015-11-24 14:41  特拉法尔加  阅读(194)  评论(0编辑  收藏  举报