zoukankan      html  css  js  c++  java
  • jquery 源码分析九

    最近一直在搞毕设,实在是没时间写博客了,零碎的时间看代码进度也不快,所以写博客一拖再拖了,今天先补一篇上来。。。

    在上次写得setDocument以后,紧接着的是一些零碎的功能函数

     1 Sizzle.matches = function( expr, elements ) {
     2     return Sizzle( expr, null, null, elements );
     3 };
     4 
     5 Sizzle.matchesSelector = function( elem, expr ) {
     6     // 设置document以防万一
     7     if ( ( elem.ownerDocument || elem ) !== document ) {
     8         setDocument( elem );
     9     }
    10 
    11     // 确保属性值被引号包裹
    12     expr = expr.replace( rattributeQuotes, "='$1']" );
    13 
    14     if ( support.matchesSelector && documentIsHTML &&
    15         ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
    16         ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
    17 
    18         try {
    19             var ret = matches.call( elem, expr );
    20 
    21             // 在IE9下matchesSelector会返回false(在IE10+情况下,开发者模式调到IE9,8是正常的,IETester下返回false)
    22             if ( ret || support.disconnectedMatch ||
    23                     // 同样的,在IE9下,这种无关节点被认为是在文档片段中
    24                     elem.document && elem.document.nodeType !== 11 ) {
    25                 return ret;
    26             }
    27         } catch(e) {}
    28     }
    29 
    30     return Sizzle( expr, document, null, [elem] ).length > 0;
    31 };
    32 
    33 Sizzle.contains = function( context, elem ) {
    34     // 设置document
    35     if ( ( context.ownerDocument || context ) !== document ) {
    36         setDocument( context );
    37     }
    38     return contains( context, elem );
    39 };
    40 
    41 Sizzle.attr = function( elem, name ) {
    42     // 设置document
    43     if ( ( elem.ownerDocument || elem ) !== document ) {
    44         setDocument( elem );
    45     }
    46 
    47     var fn = Expr.attrHandle[ name.toLowerCase() ],
    48         // 防止取到Object.prototype里的属性 (jQuery #13807)
    49         val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
    50             fn( elem, name, !documentIsHTML ) :
    51             undefined;
    52     
    53     return val !== undefined ?
    54         val :
    55         support.attributes || !documentIsHTML ?
    56             elem.getAttribute( name ) :
    57             (val = elem.getAttributeNode(name)) && val.specified ?
    58                 val.value :
    59                 null;
    60 };
    61 
    62 Sizzle.error = function( msg ) {
    63     throw new Error( "Syntax error, unrecognized expression: " + msg );
    64 };

    在这边,Sizzle.matches和Sizzle.matchesSelector在最后都是以return Sizzle( expr, null, null, elements )形式返回的,由于在Sizzle中,在第四项有值时,就会跳过一个大的if语句块

    if ( documentIsHTML && !seed ) {
    }

    然后会直接跳到最后执行select函数

    return select( selector.replace( rtrim, "$1" ), context, results, seed );

    对于select函数,先放一下。。。等看到的时候再分析。。。

    接下来的是一个主要剔除重复+排序的函数,源码如下:

    Sizzle.uniqueSort = function( results ) {
        var elem,
            duplicates = [],
            j = 0,
            i = 0;
    
        // 默认确实有重复
        hasDuplicate = !support.detectDuplicates;
        sortInput = !support.sortStable && results.slice( 0 );
        results.sort( sortOrder );
    
        if ( hasDuplicate ) {
            while ( (elem = results[i++]) ) {
                if ( elem === results[ i ] ) {
                    j = duplicates.push( i );
                }
            }
            while ( j-- ) {
                results.splice( duplicates[ j ], 1 );
            }
        }
    
        // See https://github.com/jquery/sizzle/pull/225
        sortInput = null;
    
        return results;
    };

    在这里一开始先默认确实有重复项,然后在result.sort的时候,用sortOrder来排序,这个函数在setDocument中定义了,其中有一段就是设置hasDuplicate的:

    if ( a === b ) {
        hasDuplicate = true;
    }

    注:hasDuplicate在Sizzle闭包作用域中属于全局变量。

    然后是一个拿元素内文本内容的函数,主要调用了textContent,源码如下:

     1 getText = Sizzle.getText = function( elem ) {
     2     var node,
     3         ret = "",
     4         i = 0,
     5         nodeType = elem.nodeType;
     6 
     7     if ( !nodeType ) {
     8         // 如果没有nodeType,那么就认为是一个普通数组
     9         while ( (node = elem[i++]) ) {
    10             ret += getText( node );
    11         }
    12     } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
    13         // 对于元素用textContent
    14         // innerText 已被移除
    15         if ( typeof elem.textContent === "string" ) {
    16             return elem.textContent;
    17         } else {
    18             // 对子节点遍历
    19             for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
    20                 ret += getText( elem );
    21             }
    22         }
    23     } else if ( nodeType === 3 || nodeType === 4 ) {
    24         return elem.nodeValue;
    25     }
    26     // 排除注释节点
    27 
    28     return ret;
    29 };

    它用了一个递归调用的方法,防止注释等节点的混入。

    在后面就是一个

    1 Expr = Sizzle.selectors = {
    2      // .....
    3 }

    这里放了许多关于筛选元素的函数,暂时先跳过了。下一篇的话从后面的tokenize开始讲。明后天估计还是要去实验室搬砖,争取在零碎时间多看看源码,早点把下一篇发上来。。。

    这篇好像有点短了。。。

  • 相关阅读:
    《大数据——大价值、大机遇、大变革》试读
    div+csS中的一些技巧和浏览器兼容的办法
    js正则表达式
    布局 IE haslayout
    几个好的网站
    ie6 几个li上下排列会闪动的问题,嵌套div—外层div内层div都设置背景颜色,内层div背景色不显示的问题
    live()解决Jquery采用append添加的元素事件无效和获取不到添加元素的值
    SQL语句写返回一天内的纪录,得到一周内星期几的时间
    网易邮箱添加附件功能原理浅析转
    实体类序列化
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3650885.html
Copyright © 2011-2022 走看看