jQuery源码学习(2):选择器初窥
选择器初窥
代码架构:
jQuery选择器可以依照传入数据的类型分为五大类:
- 传入字符串:$("div"), $("#id"), $(".div1"),$(".div p.title")
 - 传入html代码:$("<div></div>"), $("<div>1</div><div>2</div>")
 - 传入对象:$(document), $(this)
 - 传入数组或对象字面量:$({}), $([])
 - 传入函数:$(function(){})
 
下面我们来看一下jQuery构造函数代码(jQuery-2.2.2第2832行起)的架构:
jQuery.fn.init = function(selector, context){
  if(!selector){
    // part1.处理$(null), $(undefined), $(false), $("")
  }
  if(typeof selector == "string"){   
    // part2.匹配selector并将结果传入match中 
  }
    if(match && (match[1] || !context)){
      // part3.创建标签或按#id查询
    }else{
      // part4.处理复杂选择器
    }
  }
  // 一些其他的不常见情况
  else {...}
  return jQuery.makeArray(selector, this);
}
可以发现jQ将代码依照selector的类型分为了几个部分。下面我们来依次分析这几部分的代码。
第一部分:检测没有传入值的情况
此段完整代码如下:
// HANDLE: $(""), $(null), $(undefined), $(false)
if ( !selector ) {
  return this;
}
第二部分:匹配传入的字符串
此段完整代码如下:
if ( selector[ 0 ] === "<" &&selector[ selector.length - 1 ] === ">" &&selector.length >= 3 ) {
  // Assume that strings that start and end with <> are HTML and skip the regex check
  match = [ null, selector, null ];
} else {
  match = rquickExpr.exec( selector );
}
// 匹配html标签或#id
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
通过分析rquickExpr正则表达式,我们可以得出在selector分别为以下几种值时返回值match的结构:
1. selector = "<div>"
match = [null, "<div>", null]
2. selector = "<div>content</div>"
match = [null, "<div>content</div>", null]
3. selector = "<div></div>content"
match = ["<div></div>content", "<div></div>", null]
4. selector = #id
match = [#id, null, #id]
第三部分:创建标签或者按#id查询
传入标签时:
此段完整代码如下:
// 如果是html标签
if ( match[ 1 ] ) {
// 如果传入的context是jQ对象,将其转换成原生对象
context = context instanceof jQuery ? context[0] : context; // 将传入的html字符串转换成节点数组并传入this中
jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); // 如果是$(html, props)的形式,则要设置对应属性或执行方法
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) { // 若 prop 的某一项是jQ方法
if (jQuery.isFunction(this[match])) {
this[match](context[match]); // 否则设置对应属性
} else {
this.attr(match, context[match]);
}
}
} return this;
}
// 匹配单标签
var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
关键位置的语意都已在注释中讲解过了,下面主要介绍一下$.parseHTML和$.merge这两个方法在其中的应用:
jQuery.parseHTML( data [, context ] [, keepScripts ] )
- data:需要被转换成节点的字符串
 - context:被转换的节点所存在的上下文。并没有太大用处,默认是document,在需要在iframe中进行操作时,也可以设成contentWindow。
 - keepScripts:布尔值。设置成true时允许将字符串中的<script>部分也转换成节点。
 
jQuery.merge(first, second)
我们经常用$.merge来进行数组的合并。在本例中需要强调的一点是,$.merge被用来将一个数组合并到类数组对象中。就像下面这样:
  var obj = {0: "hello", 1: "pansy", length: 2};
  var arr = ["from", "arr"];
  console.log($.merge(obj, arr));   // Object {0: "hello", 1: "pansy", 2: "from", 3: "arr", length: 4}
传入id时:
// HANDLE: $(#id)
else {
elem = document.getElementById( match[ 2 ] ); // Support: Blackberry 4.6
// gEBID returns nodes no longer in the document (#6963)
if ( elem && elem.parentNode ) { // Inject the element directly into the jQuery object
this.length = 1;
this[ 0 ] = elem;
} this.context = document;
this.selector = selector;
return this;
}
第四部分:处理复杂选择器
// 处理形如$(".class"), $("ul li+p")等等
if ( !context || context.jquery ) {
  return ( context || root ).find( selector );
// 当传入上下文是原生对象时,调用构造函数返回jQ对象
} else {
  return this.constructor( context ).find( selector );
}
此处复杂选择器全部借助$().find()方法实现,使用了sizzle引擎,我们稍后再进行介绍。
jQuery源码学习(2):选择器初窥的更多相关文章
- jquery源码学习(一)——jquery结构概述以及如何合适的暴露全局变量
		
jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jq ...
 - Hadoop源码学习笔记(3) ——初览DataNode及学习线程
		
Hadoop源码学习笔记(3) ——初览DataNode及学习线程 进入了main函数,我们走出了第一步,接下来看看再怎么走: public class DataNode extends Config ...
 - jquery源码学习笔记三:jQuery工厂剖析
		
jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...
 - jQuery源码学习扒一扒jQuery对象初使化
		
神奇的jQuery可以这样玩jQuery("#id").css()或 jQuery("#id").html() 这么玩jQuery("#id" ...
 - jQuery源码学习感想
		
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
 - jquery 源码学习(一)
		
从上边的注释看,jQuery的源码结构相当清晰.条理,不像代码那般晦涩和让人纠结 1. 总体架构 1.1 自调用匿名函数 self-invoking anonymous function 打开jQ ...
 - 读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一
		
背景: 有心学习jquery源码,苦于自己水平有限,若自己研究,耗时耗力,且读懂之日无期. 所以,网上寻找高手的源码分析.再经过自己思考,整理,验证.以求有所收获. 此篇为读高手艾伦<jQuer ...
 - jquery 源码学习(*)
		
最近在做日志统计程序,发现对方的程序是在Jquery基础上进行开发的,而公司的网站的框架是prototype.而且我也早就想了解一下Jquery源码,故决定研究Jquery源码,模拟它的方法 Jq ...
 - 菜鸟的jQuery源码学习笔记(前言)
		
前言 相信任何一名前端开发人员或者是前端爱好者都对jQuery不陌生.jQuery简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人 ...
 
随机推荐
- HDU 4635 Strongly connected(强连通分量缩点+数学思想)
			
题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...
 - 转:Loadrunner报错“Too many local variablesAction.c”解决方法
			
问题描述,在Action.c里定义数组时如果数组长度过长,如char a[1024*1024]运行时即会报错: 问题原因及解决方法如下: 1. VuGen对于局部变量可以分配的最大内存为64K,如果想 ...
 - 转:Loadrunner学习知多少--脚本录制下载操作
			
在很多时候我们可能需要对系统进行这样的脚本开发,模拟用户点击一个下载链接,然后弹出下载框,选择保存,用来测试在大量用户下载时服务器的性能.但是现在大家对于这种脚本的处理方式往往是通过关联和C 语言的文 ...
 - linux无法解析主机地址(could not resolve host)解决办法
			
修改/etc/hosts文件: ip地址 域名 例:192.30.253.120 codeload.github.com
 - java开发第四天——莫名其妙的一天
			
搞了一天的ACM,欲哭无泪,消化的不好打了一天的嗝,然后在机房睡了一个下午,感觉还真的有点对不起队友的说.别的借口我也不找了,确实是自己不努力,时至今日,一切都是我咎由自取.等这次项目一结束我就全身心 ...
 - 고 해서: 表示在做B的各种理由中, A是代表性的理由
			
1. 날씨도 좋고해서 산책이나 하려고 해요. 2. 할 일도 없고해서 일찍 돌어왔어요. 3. 기분도 우울하고 해서 친구란 술 마시기로 했어요. 可以加过去式和将来时使用 1. 수업도 끝 ...
 - Excel相关问题
			
Excel默认永远使用最后安装的那个Excel版本打开.但是如果有一个Excel已经启动了,则使用那个Excel打开. 1.打开“开发工具”选项卡2007中:[Excel选项]-[常用]2010中:[ ...
 - TIdTCPClient 详解
			
转发地址:http://blog.csdn.net/cowcga/article/details/6198382 关于TIdTCPClient的几种方法 收藏 其实Indy比较简单,但是可以提供的方法 ...
 - 转 SQL 基础--> NEW_VALUE 的使用
			
--=============================== -- SQL 基础--> NEW_VALUE 的使用 --=============================== 通常 ...
 - 关于arguments.callee.caller.arguments[0]获得event的一些问题
			
先从一个简单的例子说起,一个简单的button控件如下: < input type ='button' name ='mybtn' id ='mybtn' onclick ='myFun ...