• jQuery1.11源码分析(8)-----jQuery调用Sizzle引擎的相关API


    之所以把这部分放在这里,是因为这里用到了一些基本API,前一篇介绍过后才能使用。

    //jQuery通过find方法调用Sizzle引擎
    //jQuery通过find方法调用Sizzle引擎
    jQuery.find = Sizzle;
    jQuery.expr = Sizzle.selectors;
    jQuery.expr[":"] = jQuery.expr.pseudos;
    jQuery.unique = Sizzle.uniqueSort;
    jQuery.text = Sizzle.getText;
    jQuery.isXMLDoc = Sizzle.isXML;
    jQuery.contains = Sizzle.contains;
    
    
    
    var rneedsContext = jQuery.expr.match.needsContext;
    
    //匹配没有其他如class等任何属性的标签,就是简单标签,
    //如<input />和<div></div>
    var rsingleTag = (/^<(w+)s*/?>(?:</1>|)$/);
    
    
    //当selector为 .header这样的形式则为简单选择符
    var risSimple = /^.[^:#[.,]*$/;
    
    // Implement the identical functionality for filter and not
    //比较难啃的一个函数,传入参数有几种用法。后面的多个过滤函数都依赖于这个函数
    //第一个参数表示element元素集,第二个参数传入过滤函数、DOM、选择符、数组,第三个参数为预设结果
    function winnow( elements, qualifier, not ) {
    	if ( jQuery.isFunction( qualifier ) ) {
    		return jQuery.grep( elements, function( elem, i ) {
    			/* jshint -W018 */
    			return !!qualifier.call( elem, i, elem ) !== not;
    		});
    
    	}
    
    	if ( qualifier.nodeType ) {
    		return jQuery.grep( elements, function( elem ) {
    			return ( elem === qualifier ) !== not;
    		});
    
    	}
    
    	if ( typeof qualifier === "string" ) {
    		if ( risSimple.test( qualifier ) ) {
    			return jQuery.filter( qualifier, elements, not );
    		}
    
    		qualifier = jQuery.filter( qualifier, elements );
    	}
    
    	return jQuery.grep( elements, function( elem ) {
    		return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
    	});
    }
    
    //过滤函数
    jQuery.filter = function( expr, elems, not ) {
    	var elem = elems[ 0 ];
    
    	if ( not ) {
    		expr = ":not(" + expr + ")";
    	}
        //其实这两个区别不大,都要调用Sizzle
    	return elems.length === 1 && elem.nodeType === 1 ?
    		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
    		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
    			return elem.nodeType === 1;
    		}));
    };
    
    //开始jQuery对象的原型进行扩展
    jQuery.fn.extend({
    	find: function( selector ) {
    
    		var i,
    			ret = [],
    			self = this,
    			len = self.length;
            //当传入的参数是字符串类型时,调用下面的filter方法,本质是调用上面的winnow,winnow里又视情况调用sizzle
    		if ( typeof selector !== "string" ) {
    			return this.pushStack( jQuery( selector ).filter(function() {
                    console.log('find');
                    console.log(self);
    				for ( i = 0; i < len; i++ ) {
                        //如果self包含符合selector的this,注意这里的this是新的jQuery对象
    					if ( jQuery.contains( self[ i ], this ) ) {
    						return true;
    					}
    				}
    			}) );
    		}
            //否则以self[i]为查找上下文context进行查找
    		for ( i = 0; i < len; i++ ) {
    			jQuery.find( selector, self[ i ], ret );
    		}
    
    		// Needed because $( selector, context ) becomes $( context ).find( selector )
            //这里是正常的压栈和选择符拼接
    		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
    		ret.selector = this.selector ? this.selector + " " + selector : selector;
    		return ret;
    	},
    	filter: function( selector ) {
    		return this.pushStack( winnow(this, selector || [], false) );
    	},
    	not: function( selector ) {
    		return this.pushStack( winnow(this, selector || [], true) );
    	},
    	is: function( selector ) {
            //通过winnow返回的长度来判断
    		return !!winnow(
    			this,
    
    			// If this is a positional/relative selector, check membership in the returned set
    			// so $("p:first").is("p:last") won't return true for a doc with two "p".
    			typeof selector === "string" && rneedsContext.test( selector ) ?
    				jQuery( selector ) :
    				selector || [],
    			false
    		).length;
    	}
    });
    
  • 相关阅读:
    【总结】搜索
    【luogu】p2296 寻找道路
    【luogu】p2058 海港
    【总结】二叉搜索树
    【总结】线段树
    【总结】矩阵快速幂
    【笔记】很基础的数论知识
    【总结】扩展欧几里得算法
    【总结】二分查找
    【高精度乘法】例1.4 课本185页
  • 原文地址:https://www.cnblogs.com/suprise/p/3662110.html
Copyright © 2020-2023  润新知