我爱编程

JQuery 笔记(五)【96~283】给JQ对象添加方法和属性

2016-02-18  本文已影响202人  8eeb5fce5842

【101~194】 init( ) : 属性初始化和参数管理

框架:

行数 代码 作用
101 init: function( selector, context, rootjQuery ) {...} 头尾
105~107 if ( !selector ) return this; 传入的是不正确直接返回,$(""), $(null), $(undefined), $(false)
109~172 if ( typeof selector === "string" ) {...} 处理非空字符串,如$('#div1') $('.box') $('div') $('#div1 div.box'),或用来创建的$('<li>') $('<li>1</li><li>2</li>')
174~178 if ( selector.nodeType ) {...} 对DOM元素进行处理,如$(this) $(document)
182~184 if ( jQuery.isFunction( selector ) ) {...} 对函数进行处理,如$(function(){})
186~189 if ( selector.selector !== undefined ) {...} 处理传参为jQuery对象,如$( $( '#div1' ) )
191 return jQuery.makeArray( selector, this ); 处理数组,如json,如$([]) $({})

101 笔记:

**【101】init: function( selector, context, rootjQuery ) {...} **


【109~172】if ( typeof selector === "string" ) {...} 源码笔记:

// 传入的是一个字符串(非空),如$('#div1') $('.box') $('div')  $('#div1 div.box')
// 或用来创建的$('<li>')  $('<li>1</li><li>2</li>')
if ( typeof selector === "string" ) {

    // 判断是否为标签
    if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
        match = [ null, selector, null ];// 是标签的扔进match里,如$('<li>')   $('<li>1</li><li>2</li>')
                                         //match = [ null, '<li>1</li><li>2</li>', null ];

    } else {// 不是标签的,如$('#div1') $('.box') $('div')  $('#div1 div.box')
            //$('<li>hello')也是这里
        match = rquickExpr.exec( selector );// 75行的正则,rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
                                            //                                        匹配标签 | 匹配#ID
    }                                      // $('#div1')------> match = [ '#div1',      null,  'div1' ];
                                            // $('<li>hello')--> match = [ '<li>hello', '<li>',  null ];
                                            // 因为子项1只匹配标签,所以hello会被忽略

                                           // $('.box') $('div')  $('#div1 div.box')这几种匹配不到match=null;

    // match在$('<li>') $('<li>1</li><li>2</li>') $('#div1')情况下为真

    // match = [ '<li>hello', '<li>',  null ];
    // match = [ null, '<li>1</li><li>2</li>', null ];处理这两种形式
    if ( match && (match[1] || !context) ) {

        if ( match[1] ) {//进一步判断 : if(){  $('<li>')  }  else {  $('#div1')   }
            context = context instanceof jQuery ? context[0] : context;// 创建标签的第二参没啥用
            // $('<li>',$(document))这样写时,第二参是jQuery对象,instanceof为真,0为document.
            //而$('<li>', document)这样写时,instanceof为假,第二参为document。

            jQuery.merge( this, jQuery.parseHTML(// 一参this为json,二参为数组,可合并成json
                match[1],
                context && context.nodeType ? context.ownerDocument || context : document,
                true// 二参为根节点;三参默认为false,//true则可添加<script><\/script>
            ) );

            //$('<li></li>',{title : 'hi',html : '1',css : {background:'red'}}).appendTo( 'ul' );处理该形式
            if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
            // rsingleTag匹配<li></li>空标签 && 必须是一个对象字面量{}

                for ( match in context ) {// 循环二参{}
                    // match为{}的title,html,css
                    if ( jQuery.isFunction( this[ match ] ) ) {// 判断是否为函数
                                                                   //JQ里有html方法,所以{}里有html就会直接调用该方法
                        this[ match ]( context[ match ] );     //相当于this.html( );

                    } else {// JQ中无title方法,就直接加属性
                        this.attr( match, context[ match ] );
                    }
                }
            }

            return this;// 创建标签的过程完毕了

        //处理$('#div1')形式   match = ['#div1',null,'div1']
        } else {
            elem = document.getElementById( match[2] );

            //一般浏览器判断elem就可知该ID的元素存不存在
            if ( elem && elem.parentNode ) {//Blackberry 4.6不行只判断elem,需elem.parentNode存在才行
                                            //一个元素只要存在必定有父级,如不存在则没有
                this.length = 1;// JQ选择元素时是存成了JSON形式,只存一个时,其无length属性,手动加下
                this[0] = elem;
            }

            this.context = document;// ID的作用上下文是document
            this.selector = selector;// 存的就是这个字符串,如'#div1'
            return this;// ID结束
        }

    // 除 $('<li>')  $('#div1')之外的复杂选择
    // 如 $('.box') $('div')  $('#div1 div.box')
    } else if ( !context || context.jquery ) {//但执行上下文不存在时,就去根节点找
                                              //如有上下文,且是jQuery对象,就直接去context找
        return ( context || rootjQuery ).find( selector );// rootjQuery为$(document)
                                                          // find()会在指定地方进行筛选
                                                          // $(document).find('ul li.box');
                                                          // 找复杂的标签是通过find()实现的

    } else {// 如有上下文,又不是jQuery对象,就走该处
        return this.constructor( context ).find( selector );
    }

【109~172】if ( typeof selector === "string" ) {...} 备注:

1. 代码流程
有三个参数 selector 和 context, rootjQuery :
   if( selector 是字符串 )
        if( selector 是标签 )
            扔进 match // [ null, 标签(可能内有文本), null ]
        else  // 不是标签,是#ID,或其他复杂 字符串
            正则匹配后扔进 match // null
                               // [ 标签和文本, 标签(无文本), null ]   
                               // [ #ID, null, ID ]   

        if( match 存在 || match[1] 不为 null,是标签 ) 
            if( match[1] 是标签 ) // 创建标签用的
                处理创建标签的第二参
                将 match[1] 合并为 json

                if( 是空标签 && 带标签属性 )
                    if( 属性中有JQ的方法,如html )
                        使用该方法
                    else
                         直接加属性
                创建标签结束

            else // 处理#ID, 这里 match = [ #ID, null, ID ]   
                if( 该ID在页面中存在,即 match[2] 不为 null )
                    给该 this 添加 length属性,并 this[0] = 该ID的元素;
                #ID处理结束。
        else if( 无 context || 有 context,且为JQ对象 ) 
            找到 selector 
        else // 如有上下文,又不是jQuery对象
            找到 selector 
2. 涉及到的其他知识
      var str = '<li>1</li><li>2</li>';
      var arr = jQuery.parseHTML( str); // [ 'li', 'li' ]

其有3个参数:

      1. 要转的数组。
      2. 指定根节点,如document。
      3. 布尔,默认为false。  为true时,可转script标签。
      var json = { 0:'a', 1:'b', length:2 };
      var arr = [ 'c', 'd' ];
      $.merge( json, arr );   //{ 0:'a', 1:'b', 2:'c', 3:'d', length:4 }
JQ有两种写法:
    $( 'ul', document ).find( 'li' );
           有二参,不是JQ对象,走 return context.find( selector );
           相当于 jQuery( document ).find( 'li' );

    $( 'ul', $( document ) ).find( 'li' );
           有二参,是JQ对象,走 return this.constructor( context ).find( selector );
           this.constructor --->  jQuery
           所以也相当于 jQuery( document ).find( 'li' );

【174~178】if ( selector.nodeType ) {...} 源码笔记:

    // 对DOM元素进行处理,如$(this)  $(document)
    } else if ( selector.nodeType ) {//节点类型肯定有nodeType
        this.context = this[0] = selector;// 将该节点赋到json的第0个属性上,然后设置执行上下文
        // 节点无父级的说法,所以上下文就是其本身
        this.length = 1;// 得手动的改变下json的length。
        return this;// 其实就是把所找的东西存到this,并让该this带下标、带length

【182~184】if ( jQuery.isFunction( selector ) ) {...} 源码笔记:

    // 对函数处理,$(function(){}) // 函数在这里主要充当文档加载的角色
    } else if ( jQuery.isFunction( selector ) ) {
        return rootjQuery.ready( selector );// 在根节点ready的情况下来调用该函数
    }

【182~184】if ( jQuery.isFunction( selector ) ) {...} 备注:

    // JQ中文档加载有两种写法:就是由该处实现的
    $( function () {} )
    $( document ).ready( function () {} )

【186~189】if ( selector.selector !== undefined ) {...} 源码笔记:

    // 处理 $( $( '#div1' ) )                 // 判断传的参是不是jQuery对象
    if ( selector.selector !== undefined ) { // 是的话就应有selector属性
        this.selector = selector.selector;
        this.context = selector.context;
    }//对应后,$( $( '#div1' ) ) 就等于 $( '#div1' ) 了

【191】return jQuery.makeArray( selector, this ); 源码笔记:

    // 处理传数组、json,如$([])  $({})
    return jQuery.makeArray( selector, this );
},

【191】return jQuery.makeArray( selector, this ); 备注:

    // $.makeArray( )会把类数组转成真正的数组
    // aDiv为一个节点集合,节点数为3,像数组,但却不能用数组方法
    $.makeArray( aDiv ).push( )// 已转成数组,这下可用数组方法了

    // $.makeArray( )传二参时,可转json
    $.makeArray( aDiv, { length : 0 } );
    //{ 0 :'div', 1 :'div', 2 :'div', length : 3 }
上一篇下一篇

猜你喜欢

热点阅读