前言
本篇文章是剖析Sizzle的最后一篇,上一篇文章把大概的匹配器解析过程剖析了,但是还有一个特殊的选择器规则没说到:位置伪类。(姑且称为位置伪类吧,因为它与节点在父节点的位置信息有关)
上一篇文章已经把详细的匹配器工作过程叙述了一遍,本篇文章不再叙述相关过程,只是把其中有关于位置伪类特殊处理的部分剖析一下,了解详细匹配过程移步到《jQuery源码剖析(九)——Sizzle选择器引擎之匹配器》
[Read more...]
本篇文章是剖析Sizzle的最后一篇,上一篇文章把大概的匹配器解析过程剖析了,但是还有一个特殊的选择器规则没说到:位置伪类。(姑且称为位置伪类吧,因为它与节点在父节点的位置信息有关)
上一篇文章已经把详细的匹配器工作过程叙述了一遍,本篇文章不再叙述相关过程,只是把其中有关于位置伪类特殊处理的部分剖析一下,了解详细匹配过程移步到《jQuery源码剖析(九)——Sizzle选择器引擎之匹配器》
[Read more...]
上篇文章《jQuery源码剖析(八)——Sizzle选择器引擎之解析原理》谈到一个终极匹配器superMatcher,它把候选元素集合seed筛选出最后符合规则的节点集合。如下图:
从这个图中我们知道,superMatcher的输入是DOM节点结合,输出也是DOM节点集合。这个终极匹配器里边需要一堆小的匹配器来判断当前输入的节点是否符合规则。
因此容易想到这样的匹配器的形式如:function(elem){return true;}
也即是说,输入一个DOM节点,判断一下输入节点是否符合某个匹配规则,如果符合了,那它就应该在最后的结果集里边。 [Read more...]
这篇文章的主题是解释Sizzle选择器引擎中的解析原理,以及部分源码注释。注意,这篇文章会做一下两点限制:
我接下去的几篇文章会用以下例子来逐步剖析Sizzle的解析原理以及匹配器构成原理:
1 2 3 4 5 6 7 8 9 10 11 | <div> <p> <span class="clr"> <input type="text" /> </span> </p> <div class="clr"> <input type="checkbox" name="readme" /> <p>Hello World</p> </div> </div> |
使用以下选择器S来选取节点:$(‘div .clr > input[name="readme"] + p’)。
在开始前,我们必须了解一个真相:CSS选择器的解析顺序是从右到左的。 [Read more...]
上篇文章《jQuery源码剖析(六)——类数组》最后聊到了jQuery所用到的选择器引擎Sizzle。
接下来的几篇文章会剖析一下关于Sizzle这个引擎。首先当然是选择器的概念以及Sizzle是如何分析这个选择器的。
我们知道浏览器最终会将HTML文档(或者说页面)解析成一棵DOM树,如下代码将会翻译成以下的DOM树。
1 2 3 4 5 6 7 8 9 | <div> <p> <input type="text" /> </p> <div class="clr"> <input type="checkbox" name="readme" /> <p>Hello World</p> </div> </div> |
为了操作到当中那个checkbox,我们需要有一种表述方式,使得通过这个表达式让浏览器知道我们是想要操作哪个DOM节点。
这个表述方式就是CSS选择器,它是这样表示的:div > p + .clr input[type="checkbox"]
表达的意思是,div底下的p的兄弟节点,该节点的class为clr,并且其属性type为checkbox。 [Read more...]
页面上如果有多个属性为class=”clr”的节点,通过jQuery操作可以拿到这些DOM节点,并包装为jQ对象:var doms = $(‘.clr’);
很容易就联想到doms应该返回的是一个数组。
这个问题很好解决,我们可以理解成jQuery继承了Array这个类。
于是doms可以像数组那样操作子元素。例如:
doms.length可以获取jQuery获取到的DOM节点的数目,经常会用 doms.length==0 来判断获取到的DOM是否为空或者不存在
doms[0]可以拿到第一个DOM节点对象(注意这里不是jQ对象!)
在实际的操作中,需要经常用到的这两个有关类数组的操作就够了。 [Read more...]
如果需要理解透jQuery设计的思想,那当然必须要理解什么是jQ对象。
用jQuery的时候经常会听到jQ对象,例如:var dom$ = $(“#id”); 这里的dom$我们成为jQ对象。
那到底这货是啥呢?
这里假定大部分看这篇文章的人都能够懂面向对象的基本想法,面向对象的思想本来就是抽象现实世界的东西,所以要用来讲解某些道理时是很让人接受的,我认为这也就是为什么吹面向对象在大型项目中容易维护的原因之一(因为它符合我们人的思维方式)。 [Read more...]
在浏览器把DOM树渲染好之前,javascript是无法操作没渲染好的DOM节点。
例如:
1 2 3 4 5 6 | <script> var dom = document.getElementById("test"); //由于script先执行,此时浏览器的还没渲染id为test的DOM节点,所以这里拿不到 </script> <div id="test"> </div> |
这是很多新手在操作DOM树容易犯的错:在文档DOM就绪前就取DOM节点。
jQuery提供了ready函数,你可以在ready里边添加回调,jQuery会保证在文档就绪后依次执行这些回调。 [Read more...]
接上一篇《jQuery源码剖析(二)——$.Callbacks》,对于javascript来说,回调这个概念无处不在,bang上次还抱怨nodejs里边读取文件内容都要回调,这里读取文件内容其实就是异步的场景。异步真是无处不在的:ajax请求,页面动画。
对于读取文件内容这个场景,通过$.Callbacks来表述读取某个文件的场景,就是以下代码:
1 2 3 4 5 6 7 8 9 10 | var callbacks = $.Callbacks(); callbacks.add(function(){ alert('读取到内容'); }); callbacks.add(function(content){ alert('内容:' + content); }); read('raphealguo.txt', function(content){ callbacks.fire(content); }); |
显然这样的做法不优雅,每次要读一个文件必须定义一个callback管理器实例。
而且读取文件有可能有失败的情况,这样就还得要去定义多一个callback管理器去处理失败的回调队列。 [Read more...]
上一篇《jQuery源码剖析(一)——概览&工具方法》最后说要了解一下jQuery的ready实现。
为了彻底理解jQuery的ready实现,所以需要理解什么是异步队列。
为了彻底理解jQuery的异步队列实现,所以需要理解什么是回调函数队列管理器(姑且叫这个名字吧,其实就是jQuery.Callbacks)。
可以看到学习实际上就是一个拓扑的问题,这篇文章完全是剖析$.Callbacks的原理&实现。
官方文档上写到$.Callbacks的用途:
A multi-purpose callbacks list object that provides a powerful way to manage callback lists.
$.Callbacks是在1.7的版本之后新增的,它提供了一些很优美的方法来管理回调函数队列。 [Read more...]
其实这剖析jQuery源码系列文章是我自己酝酿很久的想法,当然因为之前的不成熟以及理解不深刻一直不敢提笔写。近期阅读的书籍多,激发我写文章的欲望,于是把这个计划开始实施。
为什么要选择jQuery源码,我想对于一个前端开发人员来说,不言自明。jQuery的出现对于众多前端开发人员来说,是一个无比强大的武器。那为什么jQuery如此流行,深得大家喜欢?我认为秘籍就在于jQuery的API设计。
在jQuery的设计中,最主要的两块就是(个人看法):
对于一个库来说,第一点是必然要有所体现的,没有基础的工具方法,如何成为库。
对于Javascript来说,最重要的一块就是DOM操作,jQuery在DOM操作这块的贡献是巨大的,以至于现在很多新手完全不会用原生的JS API(例如document.getElementById等)了,jQuery把复杂的DOM选取映射到了简单的CSS选择器,对复杂的DOM操作(不同浏览器的DOM操作接口不一致)封装非常简单的委托API,以达到其核心的目的:The Write Less, Do More。 [Read more...]