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简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人 ...
随机推荐
- World Finals 1996 Uva 247 (Floyd求闭包)
思路:用Floyd求传递闭包. 附:逗号后的空格没看到,WA了好多次…….还有就是强连通分量也可以做,但是对这个题来说太麻烦,而且不方便输出,. 代码如下: #include<iostream& ...
- 分类算法-----KNN
摘要: 所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用她最接近的k个邻居来代表.kNN算法的核心思想是如果一个样本在特征空间中的k个最相似的样本中的大多数属于某一个类别,则该样本也属于 ...
- zf-关于荆州图片链接和弹出页面问题
target="_blank" 属性不能写在div 里 所以我在里面加了个a标签 这个属性的作用就是弹出一个新的页面,不会在原先的页面上换地址 如果 style 的加载图片卸载cs ...
- MyEclipse报错 Building workspace has encountered a problem Errors occurred during the build 的2种解决方法
1: Building workspace has encountered a problem Errors occurred during the build 如果报错这个 那么有可能是jar包,报 ...
- 国内apk加固的破解方法
国内apk加固的破解方法 By Bob Pan 国内的apk加固技术都使用了将原有的dex隐藏, 在运行时解压, 并且通过修改app的类加载器的方式实现加固. 参考: AndoridAPK反逆向解决方 ...
- HDU 1882 Strange Billboard(状态压缩+转置优化)
状态压缩,我们枚举第一行的所有状态,然后根据第一行去转变下面的行,枚举或者深搜直到最后最后一行,可以判断是不是所有的1都可以全部转换为0,记录所有的解,输出最小的一个就可以. 这里有一个很重要的优化, ...
- 新手常见的python报错及解决方案
此篇文章整理新手编写代码常见的一些错误,有些错误是粗心的错误,但对于新手而已,会折腾很长时间才搞定,所以在此总结下我遇到的一些问题.希望帮助到刚入门的朋友们.后续会不断补充. 目录 1.NameErr ...
- PHP中的ORM
周末找个时间好好写一写 ORM相关的东西,整理整理. 参考:http://www.cnblogs.com/52fhy/p/5353181.html http://www.cnblogs.com/52f ...
- 字符串的妙用之拼出花样的sql
条件写在前面 string sqlrequirement =""; if(dtp_sta.text==""&&dtp_end.text==&qu ...
- Ubuntu Server 重启 Apache Mysql
a. 重启 apache sudo service apache2 restart b. 重启 MySQL sudo service mysql restart