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简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人 ...
随机推荐
- ExtJS3.4升级ExtJS4.2的问题汇总(转)
ExtJS3.4升级ExtJS4.2的问题汇总 昨天心血来潮,想把自己用extjs3.4作为UI的一个原型升级到最新的extjs4.2.2. 几年前曾经将原型从2.1升级到3.4,对于extjs的版本 ...
- 判断浏览器增加标签 encodeURIComponent
var Sys = {}; var ua = navigator.userAgent.toLowerCase(); var s; var lx; (s = ua.match(/msie ([\d.]+ ...
- webpy
url处理 对于一个站点来说,URL 的组织是最重要的一个部分,因为这是用户看得到的部分,而且直接影响到站点是如何工作的,在著名的站点如:del.icio.us ,其URLs 甚至是网页界面的一部分. ...
- Zookeeper的安装和配置
1.ZooKeeper 1.1 zk可以用来保证数据在zk集群之间的数据的事务性一致.2.如何搭建ZooKeeper服务器集群 2.1 zk服务器集群规模不小于3个节点,要求各服务器之间系统时间要保持 ...
- 主机windwo7+虚拟机centos如何配置虚拟机可以上网,且与主机互ping通
/etc/sysconfig/network-scripts/ifcfg-eth0的配置如下: E=eth0PROTO=static#IPADDR=10.1.1.138IPADDR=192.168.0 ...
- Ubuntu14.04下SP_Flash_Tool_exe_Linux无法烧录
1,用命令lsusb查看usb信息. 2,vim 20-mm-blacklist-mtk.rules 输入下面内容: ATTRS{idVendor}=="0e8d",ENV{ID_ ...
- android:分享 一个很强大的LOG开关---Log.isLoggable
标签:android分享 一个很强大的log开 1.API亮点: 此API可以实现不更换APK,在出问题的手机上就直接能抓到有效log,能提升不少工作效率. 2.API介绍 最近在解决短信问题时,看到 ...
- css脱离文档流
作者:张秋怡链接:http://www.zhihu.com/question/24529373/answer/29135021来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- 加密Web.Config配置文件
protected void btnPassWord_Click(object sender, EventArgs e) { //加密 Configuration config = WebConfig ...
- space 管理
输入:表空间名字 输出:表空间下的一个文件即退出 /tmp/.sql select name from v$database; set serveroutput on; declare i1 varc ...