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;
}
});
jQuery1.11源码分析(8)-----jQuery调用Sizzle引擎的相关API的更多相关文章
- jQuery1.11源码分析(7)-----jQuery一些基本的API
这篇文章比较繁杂,主要就是把jQuery源码从上到下列出来,看我的注释就好了. jQuery源码对各种加载器做了处理. //阅读这个源码是请先了解一下概念,即时函数,工厂模式 (function( g ...
- jQuery1.11源码分析(6)-----jQuery结构总揽
(在看以下内容之前请先对原型链有一定的了解,比如:prototype是对象还是函数?) 在看jQuery的其他源码之前,必须对jQuery的数据结构有一定的了解. jQuery的核心很简单,jQuer ...
- jQuery1.11源码分析(1)-----Sizzle源码概览[原创]
最近在啃jQuery1.11源码,上来就遇到Sizzle这个jQuery的大核心,虽然已经清楚了Sizzle的用途,先绕过去也没事,但明知山有虎偏向虎山行才是我们要做的. 本文面向的阅读对象:正在学习 ...
- jQuery1.11源码分析(5)-----Sizzle编译和过滤阶段[原创]
在上一章中,我们说到在之前的查找阶段我们已经获得了待选集seed,那么这一章我们就来讲如何将seed待选集过滤,以获得我们最终要用的元素. 其实思路本质上还是不停地根据token过滤,但compile ...
- jQuery1.11源码分析(2)-----Sizzle源码中的正则表达式[原创]
看完了上篇,对Sizzle有了一个大致的了解,我们接下来就可以正式开始啃Sizzle的源码了.上来就讲matcher难度太大,先来点开胃菜,讲讲Sizzle中的各个正则表达式的作用吧(本来还想讲初始化 ...
- jQuery1.11源码分析(9)-----初始化jQuery对象的函数和关联节点获取函数
这篇也没什么好说的,初始化jQuery对象的函数要处理多种情况,已经被寒冬吐槽烂了.关联节点获取函数主要基于两个工具函数dir和sibling,前者基于指定的方向遍历,后者则遍历兄弟节点(真的不能合并 ...
- jQuery1.11源码分析(3)-----Sizzle源码中的浏览器兼容性检测和处理[原创]
上一章讲了正则表达式,这一章继续我们的前菜,浏览器兼容性处理. 先介绍一个简单的沙盒测试函数. /** * Support testing using an element * @param {Fun ...
- jQuery1.11源码分析(10)-----Callbacks模块
Callbacks模块实质上就是一个回调函数队列(当然吹得很牛逼..比如“提供了一种强大的方法来管理回调函数队列”),之所以介绍它是因为后面的Derferred模块基于它. Callbacks生成时接 ...
- jQuery1.11源码分析(4)-----Sizzle工厂函数[原创]
在用前两篇讲述完正则表达式.初始化.特性检测之后,终于到了我们的正餐——Sizzle工厂函数! Sizzle工厂函数有四个参数, selector:选择符 context:查找上下文 results: ...
随机推荐
- django字段设置null和blank的区别
null 这个选项跟数据库有关. null=True的话,数据库中该字段是NULL,即允许空值:null=False(默认)的话,数据库中该字段是NOT NULL,即不允许空值. blank 这个选项 ...
- model的封装+MJExtension 方便后续处理
// 基本模型 #import <Foundation/Foundation.h> @interface BasicDataModel : NSObject - (id)initWith ...
- 20145316GDB调试汇编堆栈
GDB调试例子的汇编堆栈 代码 直接-m32编译出现问题 编译64位Linux版本32位的二进制文件,需要安装一个库,使用指令sudo apt-get install libc6-dev-i386 编 ...
- 学习笔记——Maven实战(四)基于Maven的持续集成实践
Martin的<持续集成> 相信很多读者和我一样,最早接触到持续集成的概念是来自Martin的著名文章<持续集成>,该文最早发布于2000年9月,之后在2006年进行了一次修订 ...
- Anaconda安装更新库
平台:win64+anaconda 1. 如何查看已安装的库 打开 Anaconda Command Prompt ,在命令提示符窗口中输入以下命令: pip list # 或者 conda list ...
- PM2实用入门指南
简介 PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单. 下面就对PM2进行入门性的介绍,基本涵盖了PM2的常用的功能和 ...
- android之对话、单复框的使用
对话框 通过builder来构建一个单选框 package xidian.dy.com.chujia; import android.content.DialogInterface; import a ...
- 重构笔记---MEF框架(下)
概述 上一篇介绍了MEF的一个很简单很基本的应用,实现了MEF框架并展示了MEF框架的一些基本的要求和设置,这些基础知识很重要,接下来我们分析一下如何扩展或增强MEF框架内容. 增强的Contract ...
- 一款轻量级移动web开发框架
本帖最后由 yangzhu230 于 2013-9-11 00:39 编辑 如果我说要推荐zepto你肯定说“切,这地球人都知道,又一个标题党” 不卖关子,开门见山我推荐的是[百度]的GMU GMU是 ...
- Asp.Net MVC 中实现跨域访问
在ASP.Net webapi中可以使用 Microsoft.AspNet.WebApi.Cors 来实现: public static class WebApiConfig { public s ...