[No.8 jQuery源码解析—逐段解析

Posted 烟雨风飘渺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[No.8 jQuery源码解析—逐段解析相关的知识,希望对你有一定的参考价值。


继续咱们的jQuery源码解析。

(function(){

        

        (96 , 283给JQ对象添加一些方法和属性

        (285 , 347extend : JQ的继承方法

        (349 , 817jQuery.extend() : 扩展一些工具方法

        (877 , 2856)  Sizzle : 复杂选择器的实现

        (2880 , 3042Callbacks : 回调对象 : 对函数的统一管理

        (3043 , 3183Deferred : 延迟对象 : 对异步的统一管理

        (3184 , 3295support : 功能检测

        (3308 , 3652data() : 数据缓存

        (3653 , 3797queue() : 队列方法 : 执行顺序的管理

        (3803 , 4299attr() prop() val() addClass() : 对元素属性的操作

        (4300 , 5128on() trigger() : 事件操作的相关方法

        (5140 , 6057DOM操作 : 添加 删除 获取 包装 DOM筛选

        (6058 , 6620css() : 样式的操作

        (6621 , 7854提交的数据和ajax() : ajax() load() getJSON()

        (7855 , 8584animate() : 运动的方法

        (8585 , 8792offset() : 位置和尺寸的方法

        (8804 , 8821JQ支持模块化的模式

        (8826)  window.jQuery = window.$ = jQuery;

    })();

咱们继续讲jQuery源码,

讲之前,我先帮大家复习下之前的内容,

在之前我们讲到的是第二个部分,

给jQuery对象添加一些常见的方法和属性,

在这部分我给大家做了更细致的划分,

<script>

    jQuery.fn = jQuery.prototype//  添加实例属性和方法

        jQuery:版本

        constructor:修正指向问题

        init():初始化和参数管理

        selector:存储选择字符串

        length:this对象的长度

        toArray():this对象的长度

        get():转原生集合

        pushStack():JQ对象的入栈

        each():遍历集合

        ready():DOM加载的接口

        slice():集合的截取

        first():集合的第一项

        last():集合的最后一项

        eq():集合的指定项

        map():返回集合前一个状态

        push():(内部使用)

        sort():(内部使用)

        splice():(内部使用)

}

</script>

咱们讲到了这个init,

它是初始化和参数管理,

在init当中我们可以做哪些事情,

就是可以给jQuery传不同类型的参数,

我们我讲过它可以空,undefined,

false,该怎么处理,

或者在jQuery当中传字符串的时候,

该怎么处理。

后面还有对象啊函数该怎么处理,

我们来看一眼jQuery源码,

constructor: jQuery,  

  init: function( selector, context, rootjQuery ) {

        var match, elem;

                    ......

在这个init当中我们可以发现,

[No.8 jQuery源码解析—逐段解析(8)

在处理字符串的时候,

这里面的嵌套比较多,

所以说我们先看一下,

如果走if的话,肯定是字符串类型,

在这if当中,它又走了个if..else的判断,

if ( match && (match[1] || !context) ) {

这个if走的是创建标签和id的形式,

进来之后又做了一个if,

if ( match[1] ) {

这个if就是创建标签,

而它所对应的else是id的操作形式。

 // HANDLE: $(#id)

                } else {

                    elem = document.getElementById( match[2] );

我们上次就讲到这里,

接下来我们看一下这个id该怎么处理,

在这个id的时候,我们可以看到第一句话,

就是通过原生的getELementById这个方法,

来获取到这个id的元素

接下来,我们看一下match[2]里面存的是什么,

前面我帮大家分析过,如果是id的形式,

math这个数组,会长成什么样。

math = ['#div1',null,'div1'];

可以发现这个下标为2的是不是就是这个div1,

所以源码当中这里正好是选到我们想要的id,

存成了一个元素,存成了元素之后,

我们可以看到下面有两段注释,

// Check parentNode to catch when Blackberry 4.6 returns

 // nodes that are no longer in the document #6963

这两段注释是什么意思?

其实是这样的,

所有浏览器去判断这个元素存不存在,

就知道我们这个获取的id对不对,

但是有一种特殊情况,就是这个黑莓4.6的浏览器,

在它下光判断一下这个element可能不靠谱,

可能这个元素已经不在页面上了,

可这个居然还能找到,

这边有个详细的解释,

我们来看一下,

[No.8 jQuery源码解析—逐段解析(8)

可以看到这里有一个解释和例子,

我们先看一下这个解释是什么意思?

这里就是说可能在克隆节点的时候有问题,

其它情况好像没有这个问题。

这时候我们点击这个网址来看一下,

[No.8 jQuery源码解析—逐段解析(8)

这里会弹出来一个DIV,

Fround是空,

就说明DIV没有找到,

我们通过控制台看到这里确实没有div,

这是正确的,

但是大家如果把这个拿到黑莓4.6下,

这时确实是会找到的。

(大家有这个条件的话,可以去测试一下)

我们查看一下源代码,

这里也很简单就是克隆,删除节点的过程,

但是在黑莓4.6下,

页面上是没有的,

但它却可以找到。

    if ( elem && elem.parentNode ) {

           // Inject the element directly into the jQuery object

               this.length = 1;

               this[0] = elem;

              }

这里就是做了一个简单的处理,

elem有没有的时候,

并且看它有没有父级,

大家可以想一下,

如果一个元素可以在页面上显示,

它必然有父级,不管任何一个元素,它都有父级,

但是一个元素不存在,它这个父级就会找不到,

所以说这时用双重判断会更加保险一些,

这是一个小问题,我们了解一下就好了。

接下来,我们看到这个 this.length 给它赋了个1,

因为在咱们前面说过,

在jQuery选择元素的时候,

它是存成了一个json的形式,

并不是一个数组,

这样的话这个长度是没有的,

所以说必须手动地给它添加个.length

让它变成1,

这个JSON第0项,存的就是

这个第0的属性对应的就是这个元素,

接下来我们继续来看,

    this.context = document;

    this.selector = selector;

    return this;

  }

下边可以看到这个作用上下文,

肯定就是document,

接下来存的就是这个选择到的元素,

比如说这个元素叫#div1,

传到这个属性上,

这些都比较简单,

其实后面这个属性用到并不多,

到时候看到了再说,

然后直接 return this

就返回这个对象,

就不需要再向后去查找了,

其实已经找到了,

就不用再往后找,

那咱们id这一块就帮大家分析了一下。

我们接着继续,

  // HANDLE: $(expr, $(...))

            } else if ( !context || context.jquery ) {

                return ( context || rootjQuery ).find( selector );

我们走的就是else ... if,

可以发现上面写了:处理什么样的呢?

处理的就是 $(expr, $(...))

我们先来看一看else ..if的判断,

else if ( !context || context.jquery ) {

判断了context执行上下文,

当这个执行上下文不在的时候,

肯定是走return的,

因为后面这个或就不用看了,

不存在走的是rootjQuery 

这个变量就是我们的匹配页,

其实这个变量就是如下:

rootjQuery :$('document');

接着find的是谁呢?

findselector );

find的就是我们选择到的元素,

这个字符串,find其实就是筛选的功能,

在一个指定的节点下去进行进一步的筛选,

// find到一些元素,

// 比如ul下的class为box的li标签

$(document).find('ul li.class');

其实像这种选择到了之后,

就是一种复杂的包括标签啊class或者是组合形式的,

都是通过find来实现的,

find源码是怎么设计的呢?

// find要调的就是Sizzle

find —> sizzle

所以说更复杂的选择器就用Sizzle,

find会进一步处理,最终会调Sizzle,

这一块就是选择到的元素,

自动地添加一些length长度啊、JSON下标,

它都可以完成。

咱们继续看下面这个else,

  // HANDLE: $(expr, $(...))

} else if ( !context || context.jquery ) {

 return ( context || rootjQuery ).find( selector );

// HANDLE: $(expr, $(...))

  } else if ( !context || context.jquery ) {

  return ( context || rootjQuery ).find( selector );

可以看到当这个context 不存在的情况下,

就会走下边的这一句话,

但是当它存在上下文的时候,

它就会判断下后面的context.jquery,

这时就看看上下文是不是jQuery对象,

如果是jQuery对象,它就会走return后面的,

如果不是jQuery对象的话,

它就会走else里return后面的,

这边有点绕,我们来一点点分析,

// 比如说我们平时写的时候,是不是可以这样写

$('ul',document).find('li');

// 除了上面的写法还有一种

$('ul',$('document')).find('li');

这两种写法其实都是可以的,

那让我们来先看一下前面这种,

如果说是document原生的形式,

它的上下文是肯定找不到jQuery这个属性的,

因为这个属性是在jQuery对象下面的,

所以说它就会走else,

  // HANDLE: $(expr, context)

            // (which is just equivalent to: $(context).find(expr)

            } else {

                return this.constructor( context ).find( selector );

            }

这时候我们知道前面这个 this.constructor 属性,

对应的就是jQuery,

所以说上面的它会走else对应的就是

else : jQuery(document).find();

接着,我们来看下面这一种,

这一种如果有执行上下文的,

它就会走下面这句话:

context.jquery 

这句就为真,

为真的话就会走下面这句话,

// 走if的时候

if : jQuery(document).find();

所以说最终else if 和else,

这两块跳的都是同一个代码,

就是上面的代码,同样的,

只不过它们是处理不同的情况,

这一块字符串,咱们就分析完了,

最终其实可以发现这里面很多操作,

并没有在这个if中完成,

要像进一步学习,就要对这些方法进行了解


OK,咱们这段暂时讲到这里!



回看上一集:


别走开,下集更精彩。

喜欢文章的小伙伴,

希望大家多多转发分享,

你的分享就是我的动力!

喜欢
分享
or

以上是关于[No.8 jQuery源码解析—逐段解析的主要内容,如果未能解决你的问题,请参考以下文章

[No.4] jQuery源码解析—逐段解析

[No.5 jQuery源码解析—逐段解析

jQuery插件开发全解析

jquery请求解析xml

jQuery 源码解析一:jQuery 类库整体架构设计解析

jQuery公司源码解析