美文网首页我爱编程
JQuery 笔记(五)【96~283】给JQ对象添加方法和属性

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

作者: 8eeb5fce5842 | 来源:发表于2016-02-18 10:39 被阅读202次

    【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 ) {...} **

    • 在第63行,jQuery( )这个外部接口返回该构造函数。
      所以,$( selector, context )的这两个参数实际上是init处理的。
    • $( 'li', 'ul' ),选择ul下的li,第一个参数是要选择的元素,第二个参数是要选择元素的执行上下文。
    • $( ),可传入的参数类型非常多,init会对它们进行分类处理。

    【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. 涉及到的其他知识
    • rquickExpr.exec( selector )
      正则下的 exec(), 会找到一个匹配的数组集,在正则不加g的情况下,不光会将整体匹配到,还会匹配子项。
    • 创建标签时的第二参 $( '<li>', document )
      第二参是指定不同环境下的根节点。
      比如用 contentWindow.document 可找到 iframe 下的 document。
    • jQuery.parseHTML( )把字符串转成节点数组
      如 :
          var str = '<li>1</li><li>2</li>';
          var arr = jQuery.parseHTML( str); // [ 'li', 'li' ]
    

    其有3个参数:

          1. 要转的数组。
          2. 指定根节点,如document。
          3. 布尔,默认为false。  为true时,可转script标签。
    
    • jQuery.merge()可对数组和json进行合并
      数组和数组合并为数组。
      json和数组合并为json。
          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 }
    
    • jQuery( ).find()会在指定地方进行筛选
    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 }

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/vqlmkttx.html